我在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。我做错了什么,我该如何解决?
答案 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
如果需要更多精度,请使用十进制表示法