0
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;
}

The rest of the program shouldn't be too important to solving my problem, but in case it is, i'll post the rest of it at the bottom. Each BCD is basically an integer stored in an array. thisBCD is equal to 222, and BCD other is also equal to 222. My goal is to multiply these two BCDs together.

nthDigit is basically the same as thisBCD[DIGIT], returning a certain digit of the number.

MultiplyBy multiplies the BCD by a given int.

MultiplyByTen multiplies by 10. (duh)

addBCDs adds 2 BCDs together.

My issue is that rather than returning 49,284 ((222 * 2) + (222 * 20) + (222 * 200), the method returns 1332 (222 * (2 + 2 + 2).

Here is the rest of my program and Driver if you need them:

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
    // }
}

Driver:

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();
}

}

Turruc
  • 1
  • 1
  • 2
  • Why are you keeping your internal digits in reverse order? Doesn't make understanding your code any easier. – user207421 Nov 29 '15 at 22:50
  • @EJP I agree, it just makes things more difficult. Unfortunately, it's a school assignment, and that was one of the requirements. – Turruc Nov 29 '15 at 22:52
  • What about the rest of the methods? Are they all required? `multiplyBy(int)` in particular seems rather baroque. – markspace Nov 29 '15 at 22:59
  • @Tunuc Hard to believe, are you sure? What's the wording that says so? I've written BCD code many times and I would never do it that way. There is no apparent pedagogical benefit. Anyway you should certainly operate on the `int[]` arrays internally rather than creating a new `BCD` per digit. – user207421 Nov 29 '15 at 23:00
  • @markspace They were all required to make for the assignment, but they don't necessarily need to be called within the multiplyBCDs method. If you can find any way to make that method work, go for it. – Turruc Nov 29 '15 at 23:12
  • @EJP I understand it's confusing, but our teacher is very strict. The entire class is frustrated because of the way she wants us write things, but we don't have a lot of breathing room. That's one of the reasons I made both of the numbers 222 for this post, so that you all don't have to worry about flipping the numbers about. Sorry if it's confusing, and thanks for the help. – Turruc Nov 29 '15 at 23:17
  • You didn't answer my question. What is the actual wording that says so? – user207421 Nov 30 '15 at 00:24

1 Answers1

1

Several problems here. I'm not about to do your homework for you, but:

  1. In the add method, you're adding this.digit[count] to other.nthdigit(count). Either you should add this.digit[count] to other.digit[count] or this.nthdigit(count) to other.nthdigit(count), depending on which way the loop runs. (This problem is disguised by using test values such as 222: don't do that).

  2. The rest of the add method is basically nonsense. There is no need to create a new BCD per digit, for example: you can do all the addition into the target array directly. You need to write down the hand-method of addition and implement that. It's about five lines of code, not forty-something.

  3. There isn't really a need to make a special case out of zero in the `multiplyByTen() method, although I would probably do it for speed reasons. It isn't necessary to demonstrate your understanding of the problem.

  4. Similarly your multiplyBy() method is about four times as long as necessary. It just isn't this complicated. 4-5 lines of code only are required. Here again you're creating a new BCD per digit, which isn't necessary, and runs counter to the idea of special-casing zero elsewhere. As a matter of fact zero isn't a special case anywhere except as a performance optimization.

  5. Your multiplyBCDs() method looks quite elegant, unlike the others, but I'm not convinced it handles carries correctly.

user207421
  • 305,947
  • 44
  • 307
  • 483