python十进制比较

Anu*_*yal 13 python comparison decimal

python十进制比较

>>> from decimal import Decimal
>>> Decimal('1.0') > 2.0
True
Run Code Online (Sandbox Code Playgroud)

我期望它正确地转换2.0,但是在通过PEP 327读取之后我理解有一些原因没有意外地将float转换为Decimal,但是在这种情况下不应该像在这种情况下那样引发TypeError

>>> 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'
Run Code Online (Sandbox Code Playgroud)

所有其他运算符/ - %//等也是如此

所以我的问题是

  1. 这是正确的行为吗?(不要在cmp中引发异常)
  2. 如果我派生自己的类并且右浮动转换器基本上是十进制(repr(float_value)),有什么警告吗?我的用例只涉及价格比较

系统详细信息:Ubuntu 8.04.1上的Python 2.5.2

Ale*_*lli 25

重新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()
Run Code Online (Sandbox Code Playgroud)

换句话说,在Python 3中,它的行为完全符合您的想法; 但是在Python 2中它没有(并且永远不会在任何Python中2.*).

回复2,你会没事的-虽然,放眼gmpy什么我希望是通过法里树木双打无限精度分数转换成一种有趣的方式.如果您处理的价格精确到不超过美分,请使用'%.2f' % x而不是repr(x)! - )

而不是Decimal的子类,我使用工厂函数,如

def to_decimal(float_price):
    return decimal.Decimal('%.2f' % float_price)
Run Code Online (Sandbox Code Playgroud)

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

  • 这个答案有点过时了:decimal.Decimal和float的数值在2.7中是可比的。“在2.7版中进行了更改:浮点实例x和十进制实例y之间的比较现在基于x和y的值返回结果。在早期版本中,x &lt;y对于任何十进制实例x和y返回相同(任意)结果任何浮动实例y。” (2认同)