python长数据丢失

san*_*nta 1 python biginteger data-loss python-3.x

我刚刚开始使用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)))
Run Code Online (Sandbox Code Playgroud)

输出为:

num     6008514751432349174082765599289028910605977570 
num /2  3004257375716174771611310192874715313222975488 
num *2  6008514751432349543222620385749430626445950976 
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 7

您正在使用浮点除法,它不能以高精度处理大数字,之后您将结果转换为回归int().

不要这样做会导致数据丢失.改为使用整数(floor)除法//:

>>> 6008514751432349174082765599289028910605977570 // 2 * 2
6008514751432349174082765599289028910605977570
Run Code Online (Sandbox Code Playgroud)

如果没有地板,输入值不能被2整除,那么这当然会导致舍入错误:

>>> 6008514751432349174082765599289028910605977571 // 2 * 2
6008514751432349174082765599289028910605977570
Run Code Online (Sandbox Code Playgroud)

但根据您的确切CPU支持,浮点值的精度有限; 看看sys.float_info您的平台对浮点数的实际限制.

在我的Mac上,sys.float_info.dig告诉我我的平台支持15位精度,但是你要划分一个46位整数.这意味着当使用浮点除法时,你会丢弃大整数的底部30位数:

>>> len(str(int(6008514751432349174082765599289028910605977570 / 2) - (6008514751432349174082765599289028910605977570 // 2)))
30
Run Code Online (Sandbox Code Playgroud)

那是一个很大的精度损失.:-)