Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

java - ArrayIndexOutOfBoundsException in ten's complement arithmetic implementation

My code tries to implement an algorithm to

  • take user input for two integer numbers and an operand + or - from the console,
  • store those numbers digit by digit in an int[50], representing negative ones in ten's complement format,
  • implement (decimal) digit-by-digit add/subtract operations,
  • print the result in decimal format without leading zeroes.

However, in my current implementation there are two problems

  • When adding 99 + 9999, the printed result is 01098 instead of the expected 010098.
  • When subtracting 99 - 9999, I get an ArrayIndexOutOfBoundsException: 50 instead of the expected result -09900.
import java.util.*;

public class Program9 {
    public static String getOperand() {
        Scanner scan = new Scanner(System.in);
        String stringOfInteger;

        System.out.print("Please enter an integer up to 50 numbers: ");
        stringOfInteger = scan.nextLine();
        return stringOfInteger;
    }

    public static int[] convert(String operand) {
        int[] integer = new int[50];
        char ch;

        int position = operand.length() - 1;
        for (int i = integer.length - 1; i >= 0; i--) {
            if (position >= 0)
                ch = operand.charAt(position--);
            else
                ch = 0;
            if (ch >= '0' && ch <= '9') {
                integer[i] = ch - '0';
            } else {
                integer[i] = 0;
            }
        }
        return integer;
    }

    public static int[] add(int[] operand1, int[] operand2) {
        int[] result = new int[operand1.length];
        int carry = 0;
        for (int i = operand1.length - 1; i >= 0; i--) {
            result[i] = operand1[i] + operand2[i] + carry;
            if (result[i] / 10 == 1) {
                result[i] = result[i] % 10;
                carry = 1;
            } else
                carry = 0;
        }
        return result;
    }

    public static int[] complement(int[] operand) {
        int[] result = new int[operand.length];
        for (int i = operand.length - 1; i >= 0; i--)
            result[i] = 9 - operand[i];
        return result;
    }

    public static int[] add1(int[] operand) {
        int[] result = new int[50];
        result[49] = 1;
        for (int i = result.length - 2; i >= 0; i--)
            result[i] = 0;
        return result;
    }

    public static int[] negate(int[] operand) {
        return add(add1(operand), complement(operand));
    }

    public static void print(int[] result, String operation) {
        if (operation.charAt(0) == '+')
            System.out.print("The subtotal of the two integer = ");
        else if (operation.charAt(0) == '-')
            System.out.print("The substraction of the two integers = ");
        if (result[0] == 9) {
            result = negate(result);
            System.out.print("-");
            for (int i = 0; i < result.length; i++) {
                if (result[i] == 0 && result[i + 1] == 0)
                    continue;
                else
                    System.out.print(result[i]);
            }
        } else
            for (int i = 0; i < result.length; i++) {
                if (result[i] == 0 && result[i + 1] == 0)
                    continue;
                else
                    System.out.print(result[i]);
            }
        System.out.println();
    }

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int[] result = new int[50];
        String string1 = getOperand();
        String string2 = getOperand();
        int[] integer1 = convert(string1);
        int[] integer2 = convert(string2);
        String operation;

        System.out.print("Please enter which operation will be used (+ or -): ");
        operation = scan.nextLine();
        if (operation.charAt(0) == '+')
            add(integer1, integer2);
        else if (operation.charAt(0) == '-')
            integer2 = negate(integer2);

        result = add(integer1, integer2);

        System.out.println(Arrays.toString(integer1));
        System.out.println(Arrays.toString(integer2));
        System.out.println(Arrays.toString(add(integer1, integer2)));
        print(result, operation);
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Disclaimer: Your source code has multiple problems, but in order to keep it simple I am going to ignore most of them now and will just explain the reasons for your current problems and suggest fixes for them only.

If you check the array outputs from your main method, you see that the addition/subtraction results look good, i.e. the problem is not located in the calculation routines but in the print routine. There you have

  • duplicate code: The for loops printing the positive/negative numbers are identical.
  • a cosmetic problem: One leading zero is always printed.
  • a logical error: You check for two consecutive zeroes in order to determine where leading zeroes end and the actual number begins. But you forget that
    • within a number there can also be duplicate zeroes, e.g. within 10098 or -9900. This explains why 10098 is printed as 1098: You are suppressing the first zero from being printed.
    • if there is a zero in the last array element (e.g. 9900) you cannot check the (non-existent) subsequent element without causing an ArrayIndexOutOfBoundsException. This explains why you get the exception for -9900.

Now what can/should you do?

  • Eliminate the redundant for loop. You can use the same loop to print both positive and negative numbers.
  • Use a boolean flag in order to remember if you are still looping through leading zeroes or not.

You can change your print method like so:

public static void print(int[] result, String operation) {
    System.out.print(operation.charAt(0) == '-' ? "Difference = " : "Sum = ");
    if (result[0] == 9) {
        result = negate(result);
        System.out.print("-");
    }
    boolean leadingZero = true;
    for (int i = 0; i < result.length; i++) {
        if (leadingZero) {
            if (result[i] == 0)
                continue;
            leadingZero = false;
        }
        System.out.print(result[i]);
    }
    System.out.println(leadingZero ? "0" : "");
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...