为什么python中不同浮点数的差值可以为0?[duplicate]

mznpcxlj  于 2023-01-27  发布在  Python
关注(0)|答案(1)|浏览(182)
    • 此问题在此处已有答案**:

Float to Int type conversion in Python for large integers/numbers(2个答案)
Python large numbers (float and integer)(1个答案)
(31个答案)
17小时前关门了。
截至17小时前,社区正在审查是否重新讨论这个问题。
为什么下面代码0的结果在python3中?

a = "4.15129406851375e+17"
a = float(a)
b = "415129406851375001"
b = float(b)
a-b
f4t66c6m

f4t66c6m1#

发生这种情况是因为4151294068513750014.15129406851375e+17都大于C double的整数表示极限(Python float就是这样实现的)。
通常,C doubleIEEE 754 64位二进制浮点值,这意味着它们具有53位整数精度(float可以表示的最后连续整数值是2 ** 53 - 1,其后是2 ** 53;它不能表示2 ** 53 + 1)。问题是,415129406851375001需要59位整数精度来存储((415129406851375001).bit_length()将提供此信息)。当值对于单独的有效数(整数部分)来说太大时,浮点值的指数分量用于将较小的整数值按2的幂缩放为"粗略"。在原始值的范围内,但这意味着可表示的整数开始跳跃,首先跳跃2(当您需要〉53位时),然后跳跃4(对于〉54位),然后跳跃8(〉55位),然后跳跃16(〉56位),等等,对于每一个不能用53位表示的位,在可表示值之间跳过两倍的距离。
在您的示例中,转换为float的两个数字都具有整数值415129406851374976print(int(a), int(b))将显示真正的整数值;它们太大而没有任何小数部分),在低位丢失了精度。
如果您需要任意精确的以10为底的浮点数,请替换使用floatwith decimal.Decimal(方便的是,您的值已经是字符串,因此您不会冒在键入float和存储的实际值之间损失精度的风险);默认的精度将处理这些值,如果你需要更大的值,你可以增加它。2如果你这样做,你会得到你所期望的行为:

from decimal import Decimal as Dec  # Import class with shorter name

a = "4.15129406851375e+17"
a = Dec(a)  # Convert to Decimal instead of float
b = "415129406851375001"
b = Dec(b)  # Ditto
print(a-b)

它输出-1,如果你在交互式解释器中回显它,而不是使用print,你会看到Decimal('-1'),它是Decimal s的repr形式,但是它是数字形式的-1,如果转换成int,或者通过任何不使用repr的方法字符串化,例如print,则它仅显示为-1
在线试用!

相关问题