在 python 中,为什么 math.floor(4.9999999999999999) == 5?
In python, why does math.floor(4.9999999999999999) == 5?
我知道这是一些浮点错误,但我读到 python 具有无限精度,所以这种事情不应该发生。
独立的可运行代码:
import math
math.floor(4.9999999999999999)
在调用 math.floor
之前四舍五入到 5.0
。
>>> 4.9999999999999999 == 5.0
True
>>> import math
>>> math.floor(5.0)
5.0
获得正确行为的一种方法是使用 Decimal
(根本不使用 float
或 math
):
>>> import decimal
>>> int(decimal.Decimal('4.99999999999999999999999999999999999999999999999999999999999999999999999'
).to_integral(rounding=decimal.ROUND_DOWN))
4
仅供参考 Python float
类型是 IEEE 754 64-bit float,因此它最多可以有 2**64 个不同的值。十进制常量 4.9999999999999999 无法精确表示,因此在 Python 解析源代码时将其四舍五入为其他值(恰好是 5.0 的精确表示)。没有引号,浮点数在转换为十进制之前会被四舍五入:
>>> import decimal
>>> decimal.Decimal(4.9999999999999999)
Decimal('5')
>>> decimal.Decimal('4.9999999999999999')
Decimal('4.9999999999999999')
我知道这是一些浮点错误,但我读到 python 具有无限精度,所以这种事情不应该发生。
独立的可运行代码:
import math
math.floor(4.9999999999999999)
在调用 math.floor
之前四舍五入到 5.0
。
>>> 4.9999999999999999 == 5.0
True
>>> import math
>>> math.floor(5.0)
5.0
获得正确行为的一种方法是使用 Decimal
(根本不使用 float
或 math
):
>>> import decimal
>>> int(decimal.Decimal('4.99999999999999999999999999999999999999999999999999999999999999999999999'
).to_integral(rounding=decimal.ROUND_DOWN))
4
仅供参考 Python float
类型是 IEEE 754 64-bit float,因此它最多可以有 2**64 个不同的值。十进制常量 4.9999999999999999 无法精确表示,因此在 Python 解析源代码时将其四舍五入为其他值(恰好是 5.0 的精确表示)。没有引号,浮点数在转换为十进制之前会被四舍五入:
>>> import decimal
>>> decimal.Decimal(4.9999999999999999)
Decimal('5')
>>> decimal.Decimal('4.9999999999999999')
Decimal('4.9999999999999999')