Search code examples
javaif-statementreturnprimes

Return statement does not correctly terminate a recursive method


I have a method getNextPrime(int num) which is supposed to identify the closest prime number after the value received by the method.

If num is even, it will increment it and call itself again. If it is odd, it will run a for loop to check if it is divisible by odd numbers between 3 and num's half value. If it is then it will increase num by 2 and the method will call itself again, otherwise it will return the new num value which is a prime number.

The problem is, when the program gets to the return statement, it will jump to the if statement and return the original value of num + 1. I have been debugging this for a while and it just doesn't make sense. Wherever I place the return statement, the method just jumps to the if statement instead of terminating the method and returning the value to where it is being called from.

public int getNextPrime(int num){

    if(num % 2 == 0){
        //even numbers are not prime

        getNextPrime(++num);
    }
    else{

        for(int i = 3; i < (num + 1) / 2; i += 2){

            if(num % i == 0) {
                getNextPrime(num += 2); //consider odd numbers only
            }
        }
    }

    return num; //jumps to if and terminates
}

However, if I change the else statement to a separate if statement, if(num % 2 != 0) it works.

Why does this happen?

*Note - the values given to the method are greater than 3, the fact that 1, 2, and 3 are primes doesn't matter.


Solution

  • There is only one structural problem here. Reaching a single return does not collapse the entire call stack, it only returns to the previous invocation.

    You need to save the result of calling getNextPrime() every time and use that as the return value, so the value actually found gets passed back along the call chain and returned to the initial caller. As it stands you return only the number that was passed in since you never modify it.

    The fix is a very simple modification. Where you have

    getNextPrime(++num);
    
    ... and ...
    
    getNextPrime(num+2);
    

    replace them with

    return getNextPrime(++num);
    
    ... and ...
    
    return getNextPrime(num+2);
    

    The problem with the algorithm you chose is that it is inefficient. You need to test divisibility using smaller primes only, not all odd numbers, and only up to the square root of the original number.

    Implementation is left as an exercise.