python十进制比较

2024-04-26 01:38:50 发布

您现在位置:Python中文网/ 问答频道 /正文

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

所以我的问题是

  1. 这是正确的行为吗?(不引发cmp中的异常)
  2. 如果我得到自己的类和 右a浮子变换器基本上 十进制(repr(float_value)),是 有什么需要注意的吗?我的用例 只涉及价格比较

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


Tags: fromimporttruemoststring情况原因float
3条回答

Re 1,这确实是我们设计的行为——不管是对是错(很抱歉,如果这会使您的用例出错,但我们试图做到通用!)。

具体来说,很长一段时间以来,每个Python对象都可能与其他对象进行不平等的比较——不具有真正可比性的类型的对象会被任意比较(在给定的运行中是一致的,不一定是跨运行);主要的用例是对异类列表进行排序,以便按类型对其中的元素进行分组。

只为复数引入了一个例外,使得它们无法与任何事物相比——但那还是很多年前的事了,那时我们偶尔会漫不经心地破坏完美的用户代码。现在我们对一个主要版本(例如沿着2.*线,以及分别沿着3.*线)的向后兼容性要严格得多,尽管在2和3之间允许不兼容性——实际上,这是具有a3.*系列的整个点,让我们修正过去的设计决策,即使是不兼容的方式)。

任意的比较结果比它们的价值要麻烦得多,导致用户混淆;现在可以很容易地获得按类型分组的结果,例如,使用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中都不会)。

Re 2,你会没事的——不过,看看gmpy,我希望这是一个有趣的方法,可以通过Farey树将双精度数转换为无限精度分数。如果你要处理的价格精确到不超过美分,使用'%.2f' % x而不是repr(x)!-)

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

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

因为,一旦产生,产生的小数是一个非常普通的小数。

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

>>> 'abc' > 123
True

Decimal之所以正确,仅仅是因为它正确地遵循了规范。规范是否是正确的方法是一个单独的问题。:)

在处理浮点数时,只有一个常见的注意事项,简单地概括为:当心诸如负零、+/-无穷大和NaN等边缘情况,不要测试相等性(与下一个点相关),并指望数学稍微有点不准确。

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

如果它是“正确的”是一个意见问题,但为什么没有自动转换的理由存在于政治公众人物,这是作出的决定。需要注意的是,不能总是在浮点和十进制之间精确转换。因此转换不应该是隐式的。如果应用程序中的您知道您从来没有足够的有效数字来影响您,那么创建允许这种隐式行为的类应该不是问题。

另外,一个主要的论点是真实世界的用例并不存在。如果你在任何地方都使用十进制,可能会更简单。

相关问题 更多 >