问题
I´ve made a program that does the (usually called) hailstone sequence, The program basically does this:
creates an int (value) and assign it a value.
If the int is even, divide it by two.
If the int is odd, multiply it by three and add one. Continue this process until n is equal to one.
it seems to be working fine with most numbers, but this number 99888769, the app hangs on a negative integer. Why is this?, they say that no-one has yet been able to proove that it stops, I´m not expecting I have solved that. But would be interesting to know why my app stops. -
private void hailStoneSequence(){
int value = 99888769;
int i = 0;
boolean trueOrFalse = isOddOrEven (value);
while (value != 1){
while (trueOrFalse == true && value != 1){
i++;
int previousValue = value;
value = value / 2;
println( previousValue +" is even, so I take half: "+value);
trueOrFalse = isOddOrEven (value); // returning true or false, and inserting the newly divided number. So that it breaks loop when nescesary.
}
while (trueOrFalse == false && value != 1){
i++;
int previousValue = value;
value = (value * 3) + 1;
println (previousValue +" is odd, so I make 3n+1: "+value);
trueOrFalse = isOddOrEven (value);
}
}
println ("\n\nThe process took "+i+" to reach "+value);
}
private boolean isOddOrEven(int value){
/*
* Takes an value and returns true, if that number is even.
* Else it returns false.
*/
if (value % 2 != 0){
return false;
}else{
return true;
}
}
}
回答1:
As you keep increasing ints, they will eventually (in what might seem like a startling behavior) become negative because you are surpassing the maximum value of the int type (2^31-1), i.e. you end up changing the bit (of the int's binary representation) that is used to store the sign of the number. Use long instead.
回答2:
You actually picked an interesting starting number. Starting there, you eventually get to the number: 768879215. Multiplying this by 3 and adding 1 goes over the maximum value that an int can store (2^31-1), so it "overflows" into a negative number. The hailstone sequence does not always converge to 1 for negative numbers, and in fact in this case it repeats the following sequence forever:
-122
-61
-182
-91
-272
-136
-68
-34
-17
-50
-25
-74
-37
-110
-55
-164
-82
-41
-122
You can use long instead and your code will work up to (2^63-1), or use the BigInteger class and it will work for any number.
回答3:
Because your integer overflows. Use "long" instead, and your code will run fine, at least until your sequence even exceeds longs range.
回答4:
Your logic seems convoluted to me. Re-write your code to be cleaner and you should be able to see what is going on:
public class HailStoneSequence {
public void sequence() {
int value = 99888769;
int i = 0;
while (value != 1) {
int previousValue = value;
if (value % 2 == 0) {
value = value / 2;
System.out.println(previousValue + " is even, so I take half: " + value);
} else {
value = (value * 3) + 1;
System.out.println(previousValue + " is odd, so I make 3n+1: " + value);
}
}
i++;
System.out.println("\n\nThe process took " + i + " to reach " + value);
}
/**
* @param args
*/
public static void main(String[] args) {
HailStoneSequence instance = new HailStoneSequence();
instance.sequence();
}
}
Now if you run it you should see not that it stops, but it repeats. Thus, it generates an infinite series....
回答5:
Your initial seed value causes you to reach an integer overflow for the "int" data type. This causes a repeating sequence of negative values. You can either change to use the "long" data type or start with a different (smaller) seed value.
public class HailStoneSequence
{
public static void processSequence()
{
long value = 99888769; // works due to larger type range
// int value = 99888769; // causes negative repeating sequence
// int value = 81; // works with smaller seed
int i=0;
while(value != 1)
{
System.out.println("The value is:" + value);
i++;
if(value % 2 == 0)
{
value /= 2;
}
else
{
value = value * 3 + 1;
}
}
System.out.println("The process took " + i + " iterations to solve.");
}
public static void main(String[] args)
{
System.out.println("Begin Hailstorm:");
HailStoneSequence.processSequence();
System.out.println("End Hailstorm:");
}
}
来源:https://stackoverflow.com/questions/12270788/whats-causing-java-hailstone-sequence-to-crash-in-my-program