What's causing Java (hailstone sequence) to crash in my program

家住魔仙堡 提交于 2019-12-23 17:19:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!