我编写了一个java程序,使用collatz序列查找数字链的长度。 collatz序列为:如果数字是偶数,则将其除以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);
}
答案 0 :(得分:6)
对于数字113383
,迭代#120产生827370449
。下一次迭代以数字方式生成2482111348
,该int
太大而无法放入-1
变量,因此会导致arithmetic overflow包围负数。< / p>
从那里开始,所有迭代都会产生负数,虽然结果重复循环1
,但结果的循环终止条件long
永远不会发生,因此会产生无限循环。< / p>
但是,如果将变量类型更改为{{1}},则可以避免溢出(无论如何都是此起始编号),并且序列在247次迭代后完成。
顺便说一句,我通过简单地打印每次迭代就发现了这一点,并且它立即变得明显。你可以做同样的事情并自己解决这个问题。调试就像编码一样方便,因为我们都会遇到令我们感到惊讶的编码情况,并找到自己总是更令人满意和令人难忘的原因(所以你不会再陷入同样的陷阱)。