Cam Connor
Cam Connor

Reputation: 1231

recursion method Stack Overflow error

In my code i am just trying to make a simple program that tells you if one number can divide into another number evenly (in this case that number is 3). right now I am saying that if x (the number doesnt divide evenly add 0.01 to it, that gives me the stack overflow error. If I make the value 0.2 it says that 9 is a divisible of three when really the next thing number that divides into three after three is 6

public class divisible {

   public static void divide(double x) {
      double three = 3;
      double value = x%three;

      if (value==0) {
         System.out.println(x + " is a divisible of 3 ");
         return;
      }else{ 
         //System.out.println("x does not divide evenly into 3");
         divide(x+(.01));
      }

   }

   public static void main(String args[]) {
      divide(4);
   }
}

Upvotes: 0

Views: 150

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

The reason the recursion is infinite is a little obscure: the 0.1 cannot be represented exactly in double. When you add 0.1 to 3 ten times, you do not get a 4 - you get a number that's close to 4, but a little greater than it. That number does not divide your target evenly, so the recursion goes on to 4.1, 4.2, and so on, with no end.

The reason is the same why this loop never stops (try it!):

for (double x = 3 ; x != 4 ; x += 0.1) {
    System.out.println(x);
}

Using BigDecimal in place of double would fix the problem, because 0.1 would be represented exactly. Of course it would still print a wrong message (the "is divisible of 3" is hard-coded, even though x could be an entirely different number in the invocation when the remainder becomes zero).

Upvotes: 3

user000001
user000001

Reputation: 33317

Your problem is that you compare two doubles with ==. This will produce unreliable results, due to the way that floating point arithmetic is implemented. Your method should look like this:

public static void divide(int x) {
  int three = 3;
  int value = x%three;

  if (value==0) {
     System.out.println(x + " is a divisible of 3 ");
     return;
  }else{ 
     System.out.println("x does not divide evenly into 3");
//         divide(x+(.01));
  }

}

If you want the method to be accessed with a double argument, you can cast:

public static void divide(double x) {
    x = (int) Math.round(x);

If you want to be able to handle number larger than Integer.MAX_VALUE, you can use BigInteger

Upvotes: 1

Related Questions