Python的舍入问题

Rounding Problem with Python

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Python rounding error with float numbers

我在python中有一个舍入问题。如果我计算

32.50*0.19=6.17499999999998

但这应该是6.175。如果我把6.17499999999998四舍五入,加上两位小数,它会正确地显示6.18。所以我可以忍受。

但是如果我计算这个:

32.50*0.19*3=18.5249999999999

应该是18.525。如果我用两位小数将值18.5249999999999四舍五入,则显示18.52。

应该是18.53。我做错了什么?我该怎么解决?


每个计算机科学家都应该知道什么是浮点运算。

简而言之,您不应该依赖于浮点数的精确值,因为它们存储在内存中的方式不同。

另请参见关于它的python文档-浮点运算:问题和限制。它包含下一段:

For example, if you try to round the value 2.675 to two decimal places, you get this

>>> round(2.675, 2)
2.67

The documentation for the built-in round() function says that it
rounds to the nearest value, rounding ties away from zero. Since the
decimal fraction 2.675 is exactly halfway between 2.67 and 2.68, you
might expect the result here to be (a binary approximation to) 2.68.
It’s not, because when the decimal string 2.675 is converted to a
binary floating-point number, it’s again replaced with a binary
approximation, whose exact value is

2.67499999999999982236431605997495353221893310546875

Since this approximation is slightly closer to 2.67 than to 2.68, it’s
rounded down.


如果需要精确的算术运算,可以使用十进制模块:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import decimal
D=decimal.Decimal

x=D('32.50')*D('0.19')
print(x)
# 6.1750
print(x.quantize(D('0.01'),rounding=decimal.ROUND_UP))
# 6.18

y=D('32.50')*D('0.19')*D('3')
print(y)
# 18.5250
print(y.quantize(D('0.01'),rounding=decimal.ROUND_UP))
# 18.53


使用python中的decimal模块进行精确的浮点运算

埃多克斯1〔6〕

江户十一〔七〕号

埃多克斯1〔8〕


http://docs.python.org/library/functions.html_round


你没做错什么,这也不是Python的错。有些十进制数不能精确地表示为二进制浮点数。

就像不能用十进制(0.33333....1/3一样,也不能用二进制(0.0001100110011001100110011001100110011001100110011...写decimal 0.1一样。

解决方案A:

使用print 32.5 * 0.19—它将自动舍入结果。

解决方案B:

如果您实际需要这种精度,例如使用货币值计算时,请使用Decimal模块。

解决方案C:

使用python 3.2或python 2.7,它将在交互式会话中自动舍入结果。

1
2
3
4
Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32
Type"help","copyright","credits" or"license" for more information.
>>> 32.50 * 0.19
6.175


你没有做错什么。这是由于数字的内部表示:

例如,尝试以下操作:

1
0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1

如果需要更高的精度,请使用十进制表示法


我不认为那是错的。从python解释器中获取:

1
2
3
4
5
>>> round(18.524999999999999,2)
18.52
>>> round(6.1749999999999998,2)
6.17
>>>

在这两种情况下,被四舍五入的数字都小于5,因此向下四舍五入。18.52和6.17。

没错。

有一件事我不明白,为什么你得到6.18,而我得到6.17。我使用的是python 3.2.2(最新版本)