python十进制比较
>>> from decimal import Decimal
>>> Decimal('1.0') > 2.0
True
我希望它能正确转换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'
所有其他运算符/ - %// etc
也是如此所以我的问题是
系统详细信息:Ubuntu 8.04.1上的Python 2.5.2
答案 0 :(得分:24)
Re 1,确实是我们设计的行为 - 对或错(对不起,如果你的用例绊倒,但我们试图做到一般!)。
具体来说,长期以来每个Python对象都可能与其他所有Python对象进行不等式比较 - 不可比较的类型对象可以任意比较(在给定的运行中一致,不一定在运行中);主要用例是对异构列表进行排序,以便按类型对元素进行分组。
仅对复数引入了一个例外,使它们无法与任何东西相比 - 但这仍然是很多年前,当时我们偶尔会打破完美的用户代码。现在我们对主要版本中的向后兼容性更加严格(例如沿着2.*
行,并且与3.*
行分开,尽管不兼容性 允许在2到3之间 - 确实这就是拥有一个3.*
系列的重点,让我们即使以不兼容的方式解决过去的设计决策。)
任意比较结果比它们的价值更麻烦,导致用户混淆;现在可以很容易地获得按类型分组,例如key=lambda x: str(type(x))
的{{1}}参数;所以在Python 3中,不同类型的对象之间的比较,除非对象本身在比较方法中特别允许它,否则会引发异常:
sort
换句话说,在Python 3中,它的行为完全符合你的想法;但是在Python 2中它没有(并且永远不会在任何Python >>> decimal.Decimal('2.0') > 1.2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: Decimal() > float()
中)。
Re 2,你会没事的 - 但是,请期待gmpy我希望通过Farey树将双打转换为无限精度分数的有趣方法。如果您处理的价格精确到不超过美分,请使用2.*
而不是'%.2f' % x
! - )
我使用像
这样的工厂函数,而不是Decimal的子类repr(x)
因为,一旦产生,得到的十进制是一个非常普通的。
答案 1 :(得分:2)
大于比较有效,因为默认情况下,它适用于所有对象。
>>> 'abc' > 123
True
Decimal
是正确的,因为它正确遵循规范。规范是否是正确的方法是一个单独的问题。 :)
处理浮点数时只有正常的注意事项,简要总结如下:提防边缘情况,如负零,+ / - 无穷大和NaN,不测试相等性(与下一个点相关),并计数数学上有点不准确。
>>> print (1.1 + 2.2 == 3.3)
False
答案 2 :(得分:1)
如果它是“正确的”是一个意见问题,但PEP中存在没有自动转换的理由,那就是做出的决定。需要注意的是,您不能总是在float和decimal之间进行精确转换。因此,转换不应该是隐含的。如果您在应用程序中知道您从来没有足够的重要数字来影响您,那么创建允许这种隐式行为的类应该不是问题。
另外,一个主要论点是现实世界的用例不存在。如果你只是在任何地方使用Decimal,它可能会更简单。