提问人:olli 提问时间:1/26/2023 最后编辑:ShadowRangerolli 更新时间:1/29/2023 访问量:193
为什么python中不同浮点数的差值可以是0?[复制]
Why can the difference of different floating numbers be 0 in python? [duplicate]
问:
为什么 python3 中以下代码的结果为 0?
a = "4.15129406851375e+17"
a = float(a)
b = "415129406851375001"
b = float(b)
a-b
答:
发生这种情况是因为 和 都大于 C 的整数表示限制(这是 Python 的实现方式)。415129406851375001
4.15129406851375e+17
double
float
通常,C 是 IEEE 754 64 位二进制浮点值,这意味着它们具有 53 位整数精度(最后一个连续的整数值可以表示,后跟 ;它不能表示)。问题是,需要 59 位整数精度来存储(将提供此信息)。当一个值对于单独使用有效数(整数分量)来说太大时,浮点值的指数分量用于将较小的整数值缩放为 2 的幂,使其大致在原始值的大致范围内,但这意味着可表示的整数开始跳跃,首先是 2(因为您需要 >53 位), 然后是 4(对于 >54 位),然后是 8(>55 位),然后是 16(>56 位),依此类推,对于无法用 53 位表示的每个幅度位,在可表示值之间跳过两倍的距离。double
float
2 ** 53 - 1
2 ** 53
2 ** 53 + 1
415129406851375001
(415129406851375001).bit_length()
在您的例子中,两个数字的整数值都转换为 ,其整数值为 (将显示真正的整数值;它们太大而无法包含任何小数分量),在低数字中失去了精度。float
415129406851374976
print(int(a), int(b))
如果您需要任意精确的以 10 为基数的浮点数学运算,请将 替换为 decimal。十进制(
方便的是,您的值已经是字符串,因此您不会冒着在键入 a 的方式和存储的实际值之间失去精度的风险);默认精度将处理这些值,如果需要更大的值,可以增加它。如果这样做,则会获得预期的行为:float
float
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)
输出 .如果你在交互式解释器中回显它而不是使用 ,你会看到 ,这是 s 的形式,但它是数字的,如果转换为 ,或者通过任何不使用 的方法字符串化,例如 ,它显示为 。-1
print
Decimal('-1')
repr
Decimal
-1
int
repr
print
-1
评论
float
decimal
decimal.Decimal
-1
float