1

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

*edit:我已经测试过了,结果发现当程序在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);

}
4

1 回答 1

6

对于数字113383,迭代 #120 产生827370449。下一次迭代在数值上产生2482111348了太大而无法放入int变量的结果,因此它会导致算术溢出,并环绕为负数

从那里开始,所有迭代的结果都是负数,尽管结果重复循环通过-1,但结果的循环终止条件1永远不会发生,因此会导致无限循环。

但是,如果将变量类型更改为long,则可以避免溢出(无论如何对于此起始编号),并且序列在 247 次迭代后结束。


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

于 2014-01-27T04:36:14.997 回答