为什么java程序冻结在113882上?

时间:2014-01-27 03:47:37

标签: java freeze collatz

我编写了一个java程序,使用collat​​z序列查找数字链的长度。 collat​​z序列为:如果数字是偶数,则将其除以2,如果是奇数,则乘以3并加1。当数字达到1时序列结束。Additional Info on Collatz Sequence。 我的程序发现数字的链长从1到1百万,但它停在113382.没有显示错误信息,程序只是停止打印数字。

*编辑:我已对其进行了测试,结果发现,当程序在113383上时,链会收敛到负值。谁能解释一下呢?

我已经包含了完整的代码,因为它很短。

public static void main(String[] args) {
    int max =0, maxChain=0;
    for(int i = 2; i <1000000; i++ )
    {
        int c =i;
        int counter = 0;
        while(c != 1)
        {
            if(c%2 ==0) c/=2;
            else c= 3*c+1;
            counter++;
        }
        if(counter > maxChain)
        {
            maxChain =counter;
            max = i;
        }
        System.out.println(i);
    }
    System.out.println(max +" has a chain length of " +maxChain);

}

1 个答案:

答案 0 :(得分:6)

对于数字113383,迭代#120产生827370449。下一次迭代以数字方式生成2482111348,该int太大而无法放入-1变量,因此会导致arithmetic overflow包围负数。< / p>

从那里开始,所有迭代都会产生负数,虽然结果重复循环1,但结果的循环终止条件long永远不会发生,因此会产生无限循环。< / p>

但是,如果将变量类型更改为{{1}},则可以避免溢出(无论如何都是此起始编号),并且序列在247次迭代后完成。


顺便说一句,我通过简单地打印每次迭代就发现了这一点,并且它立即变得明显。你可以做同样的事情并自己解决这个问题。调试就像编码一样方便,因为我们都会遇到令我们感到惊讶的编码情况,并找到自己总是更令人满意和令人难忘的原因(所以你不会再陷入同样的​​陷阱)。

相关问题