为什么Python中的默认舍入函数可以修复双舍入错误?

问题描述 投票:0回答:1

我对Python中的round函数或双精度数在Python中如何表示的理解有问题。当对具有双精度舍入误差的数字进行舍入时,我发现一个非常令人困惑的行为;例如 1.01046+.00002=1.0104799999999998。当我将其四舍五入为 5 位数时,Python 报告结果为 1.01048,这是预期的结果。但我认为整个问题是 1.01046+.00002=1.0104799999999998 因为没有精确等于 1.01048 的双精度值。如果 round 接受一个 double 并返回一个 double,如果不存在这样的 double,它如何返回 1.01048?

以下代码:

print([1.01046+.00002*i for i in range(6)])

输出:

[1.01046, 1.0104799999999998, 1.0105, 1.0105199999999999, 1.01054, 1.01056]

这段代码是:

print([round(1.01046+.00002*i,5) for i in range(6)])

输出:

[1.01046, 1.01048, 1.0105, 1.01052, 1.01054, 1.01056]

为什么 python 没有 1.01046+.00002*1 的精确值,python 说“我没有任何这样的数字;不过我可以给你一个非常接近的数字”,但是当我问 python 时对结果数字进行四舍五入,结果是“哦,当然,这是 1.01048”

python double rounding rounding-error
1个回答
0
投票

四舍五入的结果也不准确。但是,当打印数字时,有一个默认的有效数字位数,并且它足够接近,可以在打印时没有任何尾随错误。

如果将输出强制为小数点后 20 位,您可以看到这一点。

>>> for i in range(6):
...     val = 1.01046+.00002*i
...     print(val, round(val, 5), f'{val:.20f} {round(val, 5):.20f}')
... 
1.01046 1.01046 1.01045999999999991381 1.01045999999999991381
1.0104799999999998 1.01048 1.01047999999999982279 1.01048000000000004484
1.0105 1.0105 1.01049999999999995381 1.01049999999999995381
1.0105199999999999 1.01052 1.01051999999999986279 1.01052000000000008484
1.01054 1.01054 1.01053999999999999382 1.01053999999999999382
1.01056 1.01056 1.01055999999999990280 1.01055999999999990280

val
round(val, 5)
不同时,差异在小数点后第16位之后,默认不显示。

© www.soinside.com 2019 - 2024. All rights reserved.