python十进制比较 [英] python decimal comparison

查看:164
本文介绍了python十进制比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

python十进制比较

 >>> from decimal import十进制
>>>>十进制('1.0')> 2.0
True



我希望它能够正确转换2.0, href =http://www.python.org/dev/peps/pep-0327 =nofollow noreferrer> PEP 327 我理解有一些原因没有暗示将float转换为十进制,但应该在这种情况下,它应该引发TypeError,因为它在这种情况下

 >十进制('1.0')+ 2.0 
回溯(最近一次调用):
在< string>中的文件< string>
TypeError:不支持的操作数类型为+:'十进制'和'浮点'

所有其他运算符/ - %//等



因此我的问题是


  1. 这是正确的行为吗? (不会在cmp中引发异常)

  2. 如果我派生自己的类和
    右浮点转换器基本上
    Decimal(repr(float_value)), b $ b有什么警告吗?我的用例
    仅涉及价格比较

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

解决方案

Re 1,它的确是我们设计的行为 - 对或错,因为它可能是(对不起,如果你的用例,但是我们试图是一般的。)



具体来说,长期以来,每个Python对象都可能与其他对象进行不相等比较 - 类型对象那些不是真正可比的获得任意比较(一致在给定的运行,不一定跨运行);主要用例是按类型对异构列表进行排序以对其中的元素进行分组。



仅对复数引入异常,使它们与任何东西都不可比 - 这仍然是很多年前,当我们偶尔骑兵打破完美的用户代码。现在我们对主要版本中的向后兼容性(例如沿着 2。* 行,并沿着 3。 code>一个,虽然不兼容 允许在2和3之间 - 这是有 c code>系列,让我们解决过去的设计决策,即使是在不兼容的方式)。



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

 >>>>十进制('2.0')> 1.2 
回溯(最近一次调用):
在< module>中的文件< stdin>
TypeError:unorderable types:Decimal()> float()

换句话说,在Python 3中,但在Python 2中它不会(并且不会在任何Python 2。* )。



,你会很好 - 虽然,看看 gmpy 我希望是一个有趣的方式通过Farey树将双精度转换为无限精度分数。如果你正在处理的价格精确到不超过美分,使用'%。2f'%x 而不是 repr / code>! - )



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

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

,因为一旦生成,所得到的十进制是一个完全普通的。


python decimal comparison

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

I was expecting it to convert 2.0 correctly, but after reading thru PEP 327 I understand there were some reason for not implictly converting float to Decimal, but shouldn't in that case it should raise TypeError as it does in this case

>>> 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'

so does all other operator / - % // etc

so my questions are

  1. is this right behavior? (not to raise exception in cmp)
  2. What if I derive my own class and right a float converter basically Decimal(repr(float_value)), are there any caveats? my use case involves only comparison of prices

System details: Python 2.5.2 on Ubuntu 8.04.1

解决方案

Re 1, it's indeed the behavior we designed -- right or wrong as it may be (sorry if that trips your use case up, but we were trying to be general!).

Specifically, it's long been the case that every Python object could be subject to inequality comparison with every other -- objects of types that aren't really comparable get arbitrarily compared (consistently in a given run, not necessarily across runs); main use case was sorting a heterogeneous list to group elements in it by type.

An exception was introduced for complex numbers only, making them non-comparable to anything -- but that was still many years ago, when we were occasionally cavalier about breaking perfectly good user code. Nowadays we're much stricter about backwards compatibility within a major release (e.g. along the 2.* line, and separately along the 3.* one, though incompatibilities are allowed between 2 and 3 -- indeed that's the whole point of having a 3.* series, letting us fix past design decisions even in incompatible ways).

The arbitrary comparisons turned out to be more trouble than they're worth, causing user confusion; and the grouping by type can now be obtained easily e.g. with a key=lambda x: str(type(x)) argument to sort; so in Python 3 comparisons between objects of different types, unless the objects themselves specifically allow it in the comparison methods, does raise an exception:

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

In other words, in Python 3 this behaves exactly as you think it should; but in Python 2 it doesn't (and never will in any Python 2.*).

Re 2, you'll be fine -- though, look to gmpy for what I hope is an interesting way to convert doubles to infinite-precision fractions through Farey trees. If the prices you're dealing with are precise to no more than cents, use '%.2f' % x rather than repr(x)!-)

Rather than a subclass of Decimal, I'd use a factory function such as

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

since, once produced, the resulting Decimal is a perfectly ordinary one.

这篇关于python十进制比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆