这一行:
n = int(n/2)
皈依者
n
对于小于等于的整数
2**52
,转换为浮点是无损的,但对于任何较大的值,它必须舍入到最接近的53位数字,这将丢失信息。
当然2万亿远低于这个数字
2**53
浮子精度的极限,但是从N开始的Collatz序列,经常比N高很多,2万亿左右的许多数字有超过N的序列,这一点都不令人难以置信
,而下面的数字很少。甚至有可能从2万亿开始的一长串数字经过
2**53个
但下面没有一个数字。但我不知道如何证明这样一件事,而不为每一个高达2万亿的数字建立完整的序列。(如果有一个证明,它可能会严重地依赖于在不同条件下的猜想的现有部分证明,这超出了我的工资等级)。
无论如何,解决方法很简单:要使用整数除法:
n = n // 2
下面是一个示例:
>>> n = 2**53 + 3
>>> n
9007199254740995
>>> int(n/2)
4503599627370498
>>> n//2
4503599627370497
def collatz(n):
overflow = False
i = 0
while n > 1:
if n > 2**53:
overflow=True
if n % 2 == 0:
n = int(n/2)
i += 1
else:
n = int((3*n)+1)
i += 1
return i, overflow
if __name__ == '__main__':
import sys
for arg in sys.argv[1:]:
num = int(arg.replace(',', ''))
result, overflow = collatz(num)
print(f'{arg:>30}: {result:10,} {overflow}')
当我运行这个时:
$ python3 collatz.py 989,345,275,647 1,122,382,791,663 1,444,338,092,271 1,899,148,184,679 2,081,751,768,559 2,775,669,024,745 3,700,892,032,993 3,743,559,068,799
它给了我:
989,345,275,647: 1,348 False
1,122,382,791,663: 1,356 False
1,444,338,092,271: 1,408 False
1,899,148,184,679: 1,411 False
2,081,751,768,559: 385 True
2,775,669,024,745: 388 True
3,700,892,032,993: 391 True
3,743,559,068,799: 497 True
所以,我们过去了
在同样的情况下,我们得到了错误的答案。
int(n/2)
到
n//2
989,345,275,647: 1,348 False
1,122,382,791,663: 1,356 False
1,444,338,092,271: 1,408 False
1,899,148,184,679: 1,411 False
2,081,751,768,559: 1,437 True
2,775,669,024,745: 1,440 True
3,700,892,032,993: 1,443 True
3,743,559,068,799: 1,549 True
那么,为什么它总是以相同的数量关闭?
好吧,那基本上只是你碰巧使用的具体数字的巧合。
2**53个
通过
3n+1
比较长的
而不是正确的。事实上,我只花了3次就找到了一个:
3,743,559,068,799,123
应该走326步,但需要370步。
我怀疑(但是,我甚至无法想象如何证明)许多大数字最终会在375左右的同一范围内,随着它们(对数)变大而变短一点。为什么?好吧,你能舍入的数字只有这么多,而且它们中的大多数可能都是循环的,你开始截断除法。所以,我们可以说几乎每一个数字
其舍入周期长度略大于50,并且万亿范围内的大多数数字都达到了
范围在300步以上,然后他们中的大多数将结束约375。(当然,这些数字是无中生有的,但你可以做一个蒙特卡罗模拟,看看它们实际上离现实有多远)