2009-06-30 122 views
13

蟒蛇小数比较蟒蛇小数比较

>>> from decimal import Decimal 
>>> Decimal('1.0') > 2.0 
True 

我期待它正确地转换2.0,但读通PEP 327我知道有一些理由不implictly转换浮到小数点后,但不应该在情况下,应该提高类型错误,因为在这种情况下确实

>>> Decimal('1.0') + 2.0 
Traceback (most recent call last): 
    File "<string>", line 1, in <string> 
TypeError: unsupported operand type(s) for +: 'Decimal' and 'float' 

所以做了所有其他运营商/ - %//等

所以我的问题1附件是

  1. 这是正确的行为? (不会在cmp中引发异常)
  2. 如果我推导出我自己的类和 右边的float转换器基本上 Decimal(repr(float_value)),是 有什么注意事项?我的使用情况 涉及价格

系统细节的只有比较:在Ubuntu 8.04.1

回答

24

重1,这是我们确实设计的行为 - 对或错,因为它可能是(抱歉,如果是绊倒你的使用情况,但我们试图成为一般!)。

具体来说,很久以来每个Python对象都可能受到与其他对象的不等式比较 - 实际上不可比较类型的对象可以进行任意比较(在给定的运行中一致,而不一定是跨运行) ;主要的用例是对异类列表进行排序,按类型对其中的元素进行分组。

例外引入只有复数,使他们不媲美任何东西 - 但是这仍然是很多年前,当我们偶尔漫不经心约打破完美的用户代码。如今,我们即将向后兼容一个主要版本中更严格(例如沿着2.*线,并沿3.*一个独立,虽然允许2和3之间不兼容问题 - 事实上这是的一个3.*系列,让我们解决过去的设计决策,即使在不兼容的方式)整点。

任意比较结果比他们的价值更麻烦,导致用户混淆;并且现在可以容易地获得按类型分组。 key=lambda x: str(type(x))参数为sort;所以在Python不同类型的对象,除非对象本身的特别允许在比较方法3间的比较,确实引起异常:

>>> decimal.Decimal('2.0') > 1.2 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: unorderable types: Decimal() > float() 

换句话说,在Python 3这一行为完全因为你认为它应该;但在Python 2中它不会(并且永远不会在任何Python 2.*中)。

Re 2,你会好起来的 - 尽管如此,看看gmpy我希望通过Farey树将双精度转换成无限精度的分数。如果你正在处理的价格都精确到不超过分钱,用'%.2f' % x而非repr(x) - !)

不是小数的一个子类,我会使用一个工厂的功能,如

def to_decimal(float_price): 
    return decimal.Decimal('%.2f' % float_price) 

,因为一旦产生,得到的十进制就是一个非常普通的。

1

的Python 2.5.2如果它是“正确的”,是见仁见智,但为什么没有理自动转换存在于PEP中,这就是所做出的决定。警告基本上,你不能总是完全转换浮点数和小数。因此转换不应该是隐含的。如果您在应用程序知道你永远不会有足够的显著号码,这会影响你,使类,允许这种隐含的行为不应该是一个问题。

此外,一个主要论点是,现实世界中的用例不存在。如果你在任何地方都使用Decimal,它可能会更简单。

+0

我编辑了第一个问题一点,右边我的意思是如果它不能比较转换 – 2009-06-30 06:30:37

+0

啊,我知道不会引发异常。是的,这有一个不同的原理,我同意提出异常似乎更明确。但这又是一个味道问题。 – 2009-06-30 06:39:13

2

的大于比较可行的,因为,在默认情况下,它适用于所有对象。

>>> 'abc' > 123 
True 

Decimal只是因为它正确地遵循规范。规范是否是正确的方法是一个单独的问题。 :)

只有在处理浮点数时需要注意的一些注意事项,简要总结如下:小心边界情况,例如负零点,+/-无穷大和NaN,不要测试是否相等(与下一点有关) ,并指望数学稍微不准确。

>>> print (1.1 + 2.2 == 3.3) 
False 
+2

'abc'> 123在Python 3中引发了一个TypeError异常。这是正确的事情,恕我直言。 – 2009-06-30 06:37:01