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 is2.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的错。有些十进制数不能精确地表示为二进制浮点数。
就像不能用十进制(
解决方案A:
使用
解决方案B:
如果您实际需要这种精度,例如使用货币值计算时,请使用
解决方案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(最新版本)