为什么四舍五入浮点数1.4999999999999999会产生2?

Ram*_*usa 4 python language-agnostic floating-point rounding

我一直在读一本书《编写出色的代码-理解机器》。在关于取整的部分中,它说:

如果小数位的值大于或等于可表示的总十进制值的一半,则数字应四舍五入为最小的较大数字。

意思是:

round(1.5) // equals 2
round(1.49) // equals 1
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用Python时:

x1 = 1.4999  # rounds to 1

x2 = 1.4999999999999999  # rounds to 2

print(round(x1))

print(round(x2))
Run Code Online (Sandbox Code Playgroud)

输出为:

1个

2

我用C#和Swift尝试了同样的事情,并且给出了相同的输出。因此,我认为这是一个与语言无关的话题。

但是为什么会这样呢?

我的假设是浮点单元将多余的位四舍五入,从而在应用程序员的舍入之前将“ 1.49999999999999999999999”转换为“ 1.5”。

Eri*_*hil 7

x2 = 1.4999999999999999和中print(round(x2)),有两个操作会影响该值。该round功能不能直接在数字1.4999999999999999或数字“ 1.4999999999999999”上运行。其操作数必须采用Python实现使用的浮点格式。

因此,首先将1.4999999999999999转换为浮点格式。Python并不严格要求Python实现使用哪种浮点格式,但是IEEE-754基本的64位二进制格式很常见。在此格式下,最接近1.4999999999999999的可表示值是1.5和1.49999999999999999779553950749686919152736663818359375。前者比后者更接近1.4999999999999999,因此使用前者。

因此,将1.4999999999999999转换为浮点格式将产生1.5。然后round(1.5)产生2。