Python中的舍入逻辑?

Python中的舍入逻辑?,python,rounding,Python,Rounding,在我的原始代码中,我试图用一些浮点值计算一些索引,我遇到了以下问题: >>> print int((1.40-.3)/.05) 21 但是: 我对正在发生的事说不出话来。有人能解释一下吗?这是由浮点不准确引起的: >>> print repr((1.40-.3)/.05) 21.999999999999996 您可以尝试改用Decimal类型: >>> from decimal import Decimal >>> De

在我的原始代码中,我试图用一些浮点值计算一些索引,我遇到了以下问题:

>>> print int((1.40-.3)/.05)
21
但是:


我对正在发生的事说不出话来。有人能解释一下吗?

这是由浮点不准确引起的:

>>> print repr((1.40-.3)/.05)
21.999999999999996
您可以尝试改用
Decimal
类型:

>>> from decimal import Decimal
>>> Decimal
<class 'decimal.Decimal'>
fractions.Fraction
类也可以使用。或者,你也可以绕过去:

>>> round((1.40-.3)/.05, 10) #  round to 10 decimal places
22.0

放下
打印
,您将看到实际值为:

>>> (1.40-.3)/.05
21.999999999999996
Python2
print()
(更准确地说,float.\uuu str\uuuu)通过四舍五入到两个十进制数字来实现。Python3
print()
(实际上也是
float.\uuu str\uuuu
)不这样做,它总是忠实地表示实际值(它缩写,但仅当它不更改值时)


这种不准确是浮点数固有的(包括
十进制
,尽管其不准确发生在不同的情况下)。这是一个基本问题,表示任意实数是不可能的。请参阅以获取解释。

我认为这可以直接解释:

import decimal

>>> (decimal.Decimal(1.40) -decimal.Decimal(.3))/decimal.Decimal(.05)
Decimal('21.99999999999999722444243843')
>>> (decimal.Decimal('1.40') -decimal.Decimal('.3'))/decimal.Decimal('.05')
Decimal('22')

为什么我现在投了反对票?我为你平衡了,库普托+1.@AaronHall,谢谢你。我特别同意,因为答案(例如@delnan关于
print
的观点)。尽管人们通常不需要任意精确
21.999999999996在大多数实际应用中是
22
。在大多数实际应用中,除了
int()
Decimal
可以正常工作。。。除非它没有。例如,
1/d*d!=1一般情况下。只有当你坚持某些简单的操作时,它才准确。@Cupitor不,你可以四舍五入到小数点后10位左右。@Cupitor
eval
?我希望该文件不是由用户输入的,也希望它不会被恶意用户编辑。我建议立即停止该操作,使用
float
(如
float(“12.34”)
)并取整。我明白了。但是“实际”值是22.0@你说的“实际”是什么意思?我指的是表达式的真实(数学)值。@Cupitor你显然没有读过你问题下第一条评论中的文章。实数不能用计算机来表示,只能用有理数的子集来表示。@Cupitor对于程序实际处理的值来说,这是一个谎言。在这种情况下,舍入隐藏了一个非常真实的错误/不准确,但这不会使错误消失,在其他情况下,舍入会增加错误(例如,对于1.0/3)。
>>> (1.40-.3)/.05
21.999999999999996
import decimal

>>> (decimal.Decimal(1.40) -decimal.Decimal(.3))/decimal.Decimal(.05)
Decimal('21.99999999999999722444243843')
>>> (decimal.Decimal('1.40') -decimal.Decimal('.3'))/decimal.Decimal('.05')
Decimal('22')