Reputation: 1231
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
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
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