Метод, возвращающий 222 * (2 + 2 + 2) вместо 222 * 222

public BCD multiplyBCDs(BCD other) {
    BCD thisBCD = new BCD(digit);
    BCD newBCD = new BCD(0);
    int DIGIT = 0;
    do {
        newBCD = newBCD.addBCDs(other.multiplyBy(thisBCD.nthDigit(DIGIT)));
        other = other.multiplyByTen();
        DIGIT++;
    } while (DIGIT < thisBCD.numberOfDigits());
    return newBCD;
}

Остальная часть программы не должна быть слишком важной для решения моей проблемы, но если это так, я опубликую остальную часть внизу. Каждый BCD представляет собой целое число, хранящееся в массиве. thisBCD равно 222, а BCD other также равно 222. Моя цель — перемножить эти два BCD вместе.

nthDigit в основном аналогичен thisBCD[DIGIT], возвращая определенную цифру числа.

MultiplyBy умножает BCD на заданное целое число.

MultiplyByTen умножает на 10. (да)

addBCDs добавляет 2 BCD вместе.

Моя проблема в том, что вместо того, чтобы возвращать 49 284 ((222 * 2) + (222 * 20) + (222 * 200), метод возвращает 1332 (222 * (2 + 2 + 2).

Вот остальная часть моей программы и драйвера, если они вам нужны:

public class BCD {
    private int[] digit;

    // constructor (creates array from another array)
    public BCD(int bcdDigits[]) {
        digit = new int[bcdDigits.length];
        for (int i = 0; i < digit.length; i++) {
            digit[i] = bcdDigits[i];
        }
    }

    // constructor (creates array from an int)
    public BCD(int num) {
        digit = new int[1];
        int DIGIT = num % 10;
        digit[0] = DIGIT;
        num /= 10;
        while (num > 0) {
            DIGIT = num % 10;
            addADigit(DIGIT);
            num /= 10;
        }
    }

    // returns number of digits in bcd
    public int numberOfDigits() {
        int length = digit.length;
        return length;
    }

    // returns the value of a certain digit in the BCD
    public int nthDigit(int n) {
        System.out.println("N: " + n);
        if (n >= digit.length || n < 0) {
            return -1;
        } else {
            return digit[digit.length - 1 - n];
        }
    }

    // prints the BCD backwards (printing the original number being stored in
    // the array)
    public void print() {
        for (int i = digit.length - 1; i >= 0; i--) {
            System.out.print(digit[i]);
            if (i % 3 == 0 && i != 0) {
                System.out.print(",");
            }
        }
    }

    // adds a digit to the BCD
    public void addADigit(int newdigit) {
        int[] a = new int[digit.length + 1];
        for (int i = 0; i < digit.length; i++) {
            a[i] = digit[i];
        }
        a[a.length - 1] = newdigit;
        digit = a;
    }

    public BCD addBCDs(BCD other) {
        BCD newBCD = null;
        int length;
        if (other.numberOfDigits() > digit.length) {
            length = other.numberOfDigits();
        } else {
            length = digit.length;
        }
        int count = 0;
        int temp = 0;
        int carry = 0;
        while (count < length + 1) {
            temp = 0;
            // Adds the value of digit[count] to temp, assuming that there is a
            // number available there.
            if (count <= digit.length - 1) {
                temp += digit[count];
            }

            // Adds the value of other.nthDigit(count) to temp, assuming that
            // there is a number available there.
            if (count <= (other.numberOfDigits()) - 1) {
                temp += other.nthDigit(count);
            }

            // either adds temp as the first digit of the newBCD, or adds temp %
            // 10, and sets up a carry. This section is for the first digit
            // only.
            if (count == 0 && temp < 10) {
                newBCD = new BCD(temp);
            } else if (count == 0 && temp >= 10) {
                newBCD = new BCD(temp % 10);
                carry++;
            }

            // either adds temp as the next digit of the newBCD, or adds temp %
            // 10, and sets up a carry. This section works for all digits
            // excluding the first.

            if (count > 0 && temp + carry < 10 && count < length) {
                newBCD.addADigit(temp + carry);
                carry = 0;
            } else if (count > 0 && temp + carry < 10 && count == length && temp + carry != 0) {
                newBCD.addADigit(temp + carry);
                carry = 0;
            } else if (temp + carry >= 10 && count > 0) {
                newBCD.addADigit((temp + carry) % 10);
                carry = 0;
                carry++;
            }
            count++;
        }
        return newBCD;
    }

    public BCD multiplyByTen() {
        BCD oldBCD = new BCD(digit);
        if (oldBCD.numberOfDigits() == 1 && oldBCD.nthDigit(0) == 0) {
            BCD newBCD = new BCD(0);
            return newBCD;
        } else {
            int[] newArray = new int[oldBCD.numberOfDigits() + 1];
            newArray[0] = 0;
            for (int i = 1; i < newArray.length; i++) {
                newArray[i] = oldBCD.nthDigit(i - 1);
            }
            BCD newBCD = new BCD(newArray);
            return newBCD;
        }
    }

    public BCD multiplyBy(int num) {
        int[] digit2 = new int[digit.length + num];
        System.out.println("Num: " + num);
        for (int i = 0; i < digit.length; i++) {
            digit2[i] = digit[i];
        }
        int length = 0;
        if (digit.length > num) {
            length = num;
        } else {
            length = digit.length;
        }

        if (num == 0) {
            BCD newBCD = new BCD(0);
            return newBCD;
        } else if (num == 1) {
            BCD newBCD = new BCD(digit);
            return newBCD;
        } else if (num == 10) {
            BCD newBCD = new BCD(digit);
            newBCD = newBCD.multiplyByTen();
            return newBCD;
        }
        BCD newBCD = null;
        int temp = 0;
        int carry = 0;
        for (int count = 0; count < (digit2.length); count++) {
            if (count == 0) {
                temp = digit2[count] * num;
                if ((temp + carry) == 0 && count >= length) {
                } else {
                    newBCD = new BCD((temp + carry) % 10);
                }
                carry = temp / 10;
            } else {
                temp = digit2[count] * num;
                if ((temp + carry) == 0 && count >= length) {
                } else {
                    newBCD.addADigit((temp + carry) % 10);
                }
                carry = temp / 10;
            }
        }
        return newBCD;
    }

    public BCD multiplyBCDs(BCD other) {
        BCD thisBCD = new BCD(digit);
        BCD newBCD = new BCD(0);
        int DIGIT = 0;
        do {
            newBCD = newBCD.addBCDs(other.multiplyBy(thisBCD.nthDigit(DIGIT)));
            System.out.println("thisBCD nthDigit: " + thisBCD.nthDigit(DIGIT));
            other = other.multiplyByTen();
            System.out.print("\nOther: ");
            other.print();
            DIGIT++;
        } while (DIGIT < thisBCD.numberOfDigits());
        return newBCD;
    }

    // public static BCD factorial(int num) {

    // return newBCD; // this is a different newBCD you still need to create
    // }
}

Водитель:

public class BCDDriver {
public static void main(String[] args) {
     BCD B1 = new BCD(22);
     System.out.print("B1: ");
     B1.print();
     B1 = B1.multiplyBy(2);
     System.out.print("\nProduct: ");
     B1.print();
     BCD B2 = new BCD(22);
     System.out.print("\nB2: ");
     B2.print();
     BCD B3 = new BCD(22);
     System.out.print("\nB3: ");
     B3.print();
     B2 = B2.multiplyBCDs(B3);
     System.out.print("\nProduct: ");
     B2.print();
}

}


person Turruc    schedule 29.11.2015    source источник
comment
Почему вы храните свои внутренние цифры в обратном порядке? Не облегчает понимание вашего кода.   -  person user207421    schedule 30.11.2015
comment
@EJP Я согласен, это только усложняет задачу. К сожалению, это школьное задание, и это было одним из требований.   -  person Turruc    schedule 30.11.2015
comment
А остальные методы? Все ли они обязательны? multiplyBy(int) в частности кажется довольно барокко.   -  person markspace    schedule 30.11.2015
comment
@Tunuc Трудно поверить, ты уверен? Какая формулировка говорит об этом? Я много раз писал код BCD и никогда бы так не поступил. Явной педагогической пользы нет. В любом случае, вы, безусловно, должны работать с массивами int[] внутри, а не создавать новые BCD для каждой цифры.   -  person user207421    schedule 30.11.2015
comment
@markspace Все они должны были быть выполнены для назначения, но их не обязательно вызывать в методеmultiBCDs. Если вы можете найти способ заставить этот метод работать, действуйте.   -  person Turruc    schedule 30.11.2015
comment
@EJP Я понимаю, что это сбивает с толку, но наш учитель очень строгий. Весь класс расстроен из-за того, как она хочет, чтобы мы писали вещи, но у нас мало места для передышки. Это одна из причин, по которой я сделал оба числа 222 для этого поста, чтобы вам всем не пришлось беспокоиться о переворачивании чисел. Извините, если это сбивает с толку, и спасибо за помощь.   -  person Turruc    schedule 30.11.2015
comment
Вы не ответили на мой вопрос. Какова фактическая формулировка, которая говорит об этом?   -  person user207421    schedule 30.11.2015


Ответы (1)


Здесь несколько проблем. Я не собираюсь делать за вас домашнее задание, но:

  1. В методе добавления вы добавляете this.digit[count] к other.nthdigit(count). Либо вы должны добавить this.digit[count] к other.digit[count], либо this.nthdigit(count) к other.nthdigit(count), в зависимости от того, как работает цикл. (Эта проблема маскируется с помощью тестовых значений, таких как 222: не делайте этого).

  2. Остальная часть метода добавления в основном ерунда. Например, нет необходимости создавать новые BCD для каждой цифры: вы можете выполнять все сложения напрямую в целевой массив. Вам нужно записать ручной метод сложения и реализовать его. Это около пяти строк кода, а не сорок с чем-то.

  3. На самом деле нет необходимости делать особый случай из нуля в методе `multiplyByTen(), хотя я, вероятно, сделал бы это из соображений скорости. Нет необходимости демонстрировать свое понимание проблемы.

  4. Точно так же ваш метод multiplyBy() примерно в четыре раза длиннее необходимого. Это просто не так сложно. Требуется всего 4-5 строк кода. Здесь вы снова создаете новый BCD для каждой цифры, что не является необходимым и противоречит идее использования нуля в специальном регистре в другом месте. На самом деле ноль не является особым случаем нигде, кроме оптимизации производительности.

  5. Ваш метод multiplyBCDs() выглядит довольно элегантно, в отличие от других, но я не уверен, что он правильно обрабатывает переносы.

person user207421    schedule 29.11.2015