为什么四舍五入浮点数 1.4999999999999999 会产生 2?
Why does rounding the floating-point number 1.4999999999999999 produce 2?
我一直在看书Write Great code - Understanding the Machine。在关于四舍五入的部分中说:
Numbers should be rounded to the smallest bigger number if the decimal bit value is more than or equal half the total decimal value that can be represented.
这意味着:
round(1.5) // equals 2
round(1.49) // equals 1
但是当我用 Python 尝试这个时:
x1 = 1.4999 # rounds to 1
x2 = 1.4999999999999999 # rounds to 2
print(round(x1))
print(round(x2))
输出是:
1
2
我用 C# 和 Swift 尝试了同样的事情,它给出了相同的输出。所以我认为这是一个与语言无关的话题。
但是为什么会这样呢?
我的假设是 浮点单元 在应用程序员舍入之前舍入将“1.4999999999999999999”转换为“1.5”的额外位。
在x2 = 1.4999999999999999
和print(round(x2))
中,有两个操作会影响值。 round
函数不能直接操作数字1.4999999999999999或数字“1.4999999999999999”。它的操作数必须是 Python 实现使用的浮点格式。
因此,首先将1.4999999999999999转换为浮点数格式。 Python 对于 Python 实现使用哪种浮点格式并不严格,但 IEEE-754 基本 64 位二进制格式很常见。在这种格式中,最接近 1.4999999999999999 的可表示值是 1.5 和 1.4999999999999997779553950749686919152736663818359375。前者比后者更接近1.4999999999999999,所以用前者
因此,将 1.4999999999999999 转换为浮点格式会产生 1.5。然后 round(1.5)
产生 2.
我一直在看书Write Great code - Understanding the Machine。在关于四舍五入的部分中说:
Numbers should be rounded to the smallest bigger number if the decimal bit value is more than or equal half the total decimal value that can be represented.
这意味着:
round(1.5) // equals 2
round(1.49) // equals 1
但是当我用 Python 尝试这个时:
x1 = 1.4999 # rounds to 1
x2 = 1.4999999999999999 # rounds to 2
print(round(x1))
print(round(x2))
输出是:
1
2
我用 C# 和 Swift 尝试了同样的事情,它给出了相同的输出。所以我认为这是一个与语言无关的话题。
但是为什么会这样呢?
我的假设是 浮点单元 在应用程序员舍入之前舍入将“1.4999999999999999999”转换为“1.5”的额外位。
在x2 = 1.4999999999999999
和print(round(x2))
中,有两个操作会影响值。 round
函数不能直接操作数字1.4999999999999999或数字“1.4999999999999999”。它的操作数必须是 Python 实现使用的浮点格式。
因此,首先将1.4999999999999999转换为浮点数格式。 Python 对于 Python 实现使用哪种浮点格式并不严格,但 IEEE-754 基本 64 位二进制格式很常见。在这种格式中,最接近 1.4999999999999999 的可表示值是 1.5 和 1.4999999999999997779553950749686919152736663818359375。前者比后者更接近1.4999999999999999,所以用前者
因此,将 1.4999999999999999 转换为浮点格式会产生 1.5。然后 round(1.5)
产生 2.