我刚开始使用 python (python3),因为我读到它对 euler 项目有好处,因为它可以处理非常大的数字。
现在我正在努力解决将 float 转换为 int 的一个非常简单的问题。为什么我没有得到相同的结果:
num = 6008514751432349174082765599289028910605977570
print('num {0} '.format(int(num)))
num = num / 2
print('num /2 {0} '.format(int(num)))
num = num * 2
print('num *2 {0} '.format(int(num)))
输出为:
num 6008514751432349174082765599289028910605977570
num /2 3004257375716174771611310192874715313222975488
num *2 6008514751432349543222620385749430626445950976
请您参考如下方法:
您正在使用浮点除法,它无法以如此高的精度处理大数,之后您通过将结果转换回 int() 来对结果进行取整。
不要那样做,这会导致数据丢失。使用 integer (floor) division with //相反:
>>> 6008514751432349174082765599289028910605977570 // 2 * 2
6008514751432349174082765599289028910605977570
当然这仍然会导致舍入错误,如果输入值不能被 2 整除而不用 flooring:
>>> 6008514751432349174082765599289028910605977571 // 2 * 2
6008514751432349174082765599289028910605977570
但浮点值的精度取决于您的确切 CPU 支持;见sys.float_info查看您的平台对 float 施加的确切限制。
在我的 Mac 上,sys.float_info.dig 告诉我我的平台支持 15 位精度,但您要除以 46 位整数。这意味着您在使用浮点除法时丢弃了大整数的底部 30 位:
>>> len(str(int(6008514751432349174082765599289028910605977570 / 2) - (6008514751432349174082765599289028910605977570 // 2)))
30
那是很多的精度损失。 :-)
