Python的舍入问题

时间:2011-09-22 13:11:06

标签: python rounding

  

可能重复:
  Python rounding error with float numbers

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

32.50 * 0.19 = 6.1749999999999998

但这应该是6.175。如果我将6.1749999999999998舍入为2位小数,则正确显示6.18。所以我可以忍受。

但如果我算这个:

32.50 * 0.19 * 3 = 18.524999999999999

这应该是18.525。如果我将值18.524999999999999四舍五入,则显示18.52。

它应该显示我18.53。我做错了什么,我该如何解决?

7 个答案:

答案 0 :(得分:7)

What Every Computer Scientist Should Know About Floating-Point Arithmetic

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

另见python docs - Floating Point Arithmetic: Issues and Limitations。它包含下一段:

  

例如,如果您尝试将值2.675舍入到两位小数,则得到此

     

>>> round(2.675, 2)
  2.67

     

内置round()函数的文档说明了它   舍入到最接近的值,从零开始四舍五入。自从   小数分数2.675正好在2.67和2.68之间,你   可能期望这里的结果是(二进制近似)2.68。   它不是,因为当十进制字符串2.675转换为a时   二进制浮点数,它再次被二进制替换   近似,其精确值为

     

2.67499999999999982236431605997495353221893310546875

     

由于这个近似值略微接近2.67而不是2.68,因此   四舍五入。

答案 1 :(得分:3)

如果您需要精确算术,可以使用decimal模块:

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

答案 2 :(得分:2)

使用python中的Decimal模块进行准确的浮动算术

from decimal import Decimal, ROUND_UP

print (Decimal(32.50 * 0.19 * 3).quantize(Decimal('.01'), rounding=ROUND_UP))

Output: 18.53

答案 3 :(得分:1)

你没有做错任何事,it isn't Python's fault either。有些十进制数字不能精确地表示为二元浮点数。

就像你不能用十进制(1/3)写0.33333....一样,你不能用二进制(0.1)写小数0.0001100110011001100110011001100110011001100110011...

解决方案A:

使用print 32.5 * 0.19 - 它会自动舍入结果。

解决方案B:

如果您确实需要此精度,请使用Decimal模块,例如在使用货币值进行计算时。

解决方案C:

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

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

答案 4 :(得分:1)

答案 5 :(得分:0)

我认为这不对。从Python解释器中获取:

>>> 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(最新版本)

答案 6 :(得分:0)

你没有做错任何事。这是由于数字的内部表示:

例如,试试这个:

0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1 +  0.1 + 0.1

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