3

(通常呼ばれる) 雹のシーケンスを実行するプログラムを作成しました。プログラムは基本的にこれを実行します。

int(値) を作成し、それに値を割り当てます。

int が偶数の場合は、2 で割ります。

int が奇数の場合は、3 倍して 1 を足します。n が 1 になるまで、このプロセスを続けます。

ほとんどの数値で正常に動作しているようですが、この数値 99888769 では、アプリが負の整数でハングします。これはなぜですか?、彼らは、誰もそれが止まることを証明できなかったと言います.私はそれを解決したとは思っていません. しかし、なぜ私のアプリが停止するのかを知ることは興味深いでしょう. -

    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;
    }
}

}

4

5 に答える 5

7

sを増やし続けるintと、int型の最大値(2 ^ 31-1)を超えているため、最終的に(驚くべき動作のように見えるかもしれませんが)負になります。つまり、(数値の符号を格納するために使用されるintのバイナリ表現)。long代わりに使用してください。

于 2012-09-04T20:26:20.607 に答える
3

あなたは実際に興味深い開始番号を選択しました。そこから始めて、最終的には 768879215 という数値になります。これに 3 を掛けて 1 を足すと、int が格納できる最大値 (2^31-1) を超えるため、負の数値に "オーバーフロー" します。ヘイルストーン シーケンスは、負の数に対して常に 1 に収束するとは限りません。実際、この場合、次のシーケンスが永遠に繰り返されます。

-122
-61
-182
-91
-272
-136
-68
-34
-17
-50
-25
-74
-37
-110
-55
-164
-82
-41
-122

代わりに使用longすると、コードは (2^63-1) まで機能します。または、BigIntegerクラスを使用すると、任意の数に対して機能します。

于 2012-09-04T20:34:48.387 に答える
2

整数がオーバーフローするためです。代わりに「long」を使用すると、少なくともシーケンスがlongsの範囲を超えるまで、コードは正常に実行されます。

于 2012-09-04T20:27:04.370 に答える
2

あなたの論理は私には複雑に思えます。コードをよりきれいに書き直すと、何が起こっているかを確認できるはずです。

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();
    }

}

これを実行すると、停止するのではなく、繰り返されることがわかるはずです。したがって、それは無限のシリーズを生成します....

于 2012-09-04T20:34:03.667 に答える
1

初期シード値により、「int」データ型の整数オーバーフローが発生します。これにより、一連の負の値が繰り返されます。「long」データ型を使用するように変更するか、別の (より小さい) シード値から開始することができます。

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:");
    }
}
于 2012-09-04T20:42:46.627 に答える