0

I'm implementing a Karatsuba algorithm, and am running into this exception.

Some relevant code (I can post more if needed):

From main:

int degree = (input.nextInt() + 1);
int A[] = new int[degree];
int B[] = new int[degree];

for(int i = 0; i < degree; i++)
    A[i] = input.nextInt();
for(int i = 0; i < degree; i++)
    B[i] = input.nextInt();
product = karatsuba(A, B, degree); // LINE 22

From karatsuba:

static int[] karatsuba(int[] A, int[] B, int degree) {

    int[] A_hi = new int[degree / 2];
    int[] A_lo = new int[degree / 2];
    int[] B_hi = new int[degree / 2];
    int[] B_lo = new int[degree / 2];

    int[] m1 = new int[degree / 2];
    int[] m2 = new int[degree / 2];

    for(int i = (degree / 2); i < degree; i++) {
        A_hi[i - degree / 2] = A[I]; // LINE 50
        B_hi[i - degree / 2] = B[i];
        System.out.println(A_hi[i - degree / 2] + " " + A[i] + "   " + B_hi[i - degree / 2] + " " + B[i]);
    }

    for(int i = 0; i < (degree / 2); i++) {
        A_lo[i] = A[i];
        B_lo[i] = B[i];
        m1[i] = A_lo[i] + A_hi[i];
        m2[i] = B_lo[i] + B_hi[i];
    }  

    int[] r = new int[(degree * 2) - 1];
    int[] r_m = karatsuba(m1, m2, (degree / 2)); // LINE 63
    int[] r_lo = karatsuba(A_lo, B_lo, (degree / 2));
    int[] r_hi = karatsuba(A_hi, B_hi, (degree / 2));

From there I load the r_ arrays into r[] for returning to main. Here is a sample input that is used to load A[] and B[]. I'm using arrays for polynomial multiplication, the values being coefficients.

I'm not very familiar with this exception, but from what I understand, ArrayIndexOutOfBoundsException: 0 means I'm trying to access an array using index 0 when that index doesn't exist in the bounds of the array.

My confusion is, for A[] and B[], I verified that input was getting the correct numbers, so it's initialized and has values up to degree. And for A_hi and B_hi, I initialize the arrays, and load values one by one. I checked to see what values were being loaded into A_hi[] and B_hi[] with this line:

System.out.println(A_hi[i - degree / 2] + " " + A[i] + "   " + B_hi[i - degree / 2] + " " + B[i]);

Which led to this output –– so the values are being loaded how I intend.

So which array am I accessing with 0 that isn't properly initialized? Or is there another problem that I'm not understanding?

Here is the full error list

DanBan
  • 21
  • 5
  • Can you post more complete code which exhibits the error? – Makoto Dec 15 '18 at 22:04
  • @Makoto Sure, I'll make an edit right now. I'm hesitant to post too much code due to plagiarism issues as I am a student, so let me know if you need any more after my edit! – DanBan Dec 15 '18 at 22:05
  • Suppose degree==1. Then your array has size zero and the first statement in the loop crashes. – FredK Dec 15 '18 at 22:05
  • @FredK So only in the very last step of the recursion does it hit degree == 1? Should I use a while loop instead to make sure degree >= 2 or is there a better way to go about this? – DanBan Dec 15 '18 at 22:11

1 Answers1

2

Your code is prone to performing an out-of-bounds array access. Specifically, consider this simplified variation:

int[] A_hi = new int[degree / 2];

for(int i = (degree / 2); i < degree; i++) {
    A_hi[i - degree / 2] = 1;
}

Array A_hi has degree / 2 elements, and you set degree - degree / 2 elements. But if the value of degree is odd then degree - degree / 2 is one greater than degree / 2, so you overrun the array bounds on the last iteration. In particular, if degree == 1 then there is only one iteration, with i == 0, and A_hi has length zero. That will produce exactly the exception you observe.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • So the odd degree problem isn't an issue because degree will always be even (it's part of the assignment). For the other issue, where degree == 1, I'm not sure how to work around that problem. I'm toying with adding an if statement that returns a recursion call if degree < 2 but that doesn't seem to be helping. Any ideas how to simplify? – DanBan Dec 15 '18 at 22:34
  • @DanBan, the degree-1 problem is just a special case of the odd-degree problem, not a separate issue. And although the *topmost* recursive call may always specify even degree, unless the degree is always a power of 2, you will sometimes run into the odd-degree problem for degrees other than 1. – John Bollinger Dec 15 '18 at 22:40
  • Sorry that is what I meant. The input will always be 1 less than a power of 2. And the way I've built my program, I add one to the degree to account for degree 0 variables, so it'll always be a power of 2 @John Bollinger – DanBan Dec 15 '18 at 22:46
  • Ok, then you should make the base case of your recursion be the one where the arrays have length 1. Catch that with an appropriate conditional statement, and perform the appropriate behavior. It is unclear to me what the actual behavior required for that case would be in your particular implementation, but this *is* an academic exercise, so .... – John Bollinger Dec 15 '18 at 22:55
  • I appreciate all the help. As you said, it's an exercise, I'm looking for guidance, not the answer :) Thanks! – DanBan Dec 15 '18 at 22:58