为什么 Decimal('0') > 9999.0 在 Python 中正确吗?

发布于 2024-08-24 10:40:57 字数 947 浏览 4 评论 0原文

这在某种程度上与我的问题为什么在Python中''> 0 True?

在 Python 2.6.4 中:

>> Decimal('0') > 9999.0
True

答案到我最初的问题我明白,当比较 Python 2.x 中不同类型的对象时,类型是按名称排序的。但在这种情况下:

>> type(Decimal('0')).__name__ > type(9999.0).__name__
False

为什么 Decimal('0') > 9999.0 == True 那么呢?

更新:我通常在 Ubuntu 上工作(Linux 2.6.31-20-generic #57-Ubuntu SMP Mon Feb 8 09:05:19 UTC 2010 i686 GNU/Linux,Python 2.6.4(r264:75706,2009年12月7日,18) :45:15) [GCC 4.4.1] 在 linux2) 上。在 Windows 上(WinXP Professional SP3,Python 2.6.4(r264:75706,2009 年 11 月 3 日,13:23:17)[MSC v.1500 32 位(Intel)] on win32)我原来的声明工作方式不同:

>> Decimal('0') > 9999.0
False

我更困惑现在。 %-(

This is somehow related to my question Why is ''>0 True in Python?

In Python 2.6.4:

>> Decimal('0') > 9999.0
True

From the answer to my original question I understand that when comparing objects of different types in Python 2.x the types are ordered by their name. But in this case:

>> type(Decimal('0')).__name__ > type(9999.0).__name__
False

Why is Decimal('0') > 9999.0 == True then?

UPDATE: I usually work on Ubuntu (Linux 2.6.31-20-generic #57-Ubuntu SMP Mon Feb 8 09:05:19 UTC 2010 i686 GNU/Linux, Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15) [GCC 4.4.1] on linux2). On Windows (WinXP Professional SP3, Python 2.6.4 (r264:75706, Nov 3 2009, 13:23:17) [MSC v.1500 32 bit (Intel)] on win32) my original statement works differently:

>> Decimal('0') > 9999.0
False

I even more puzzled now. %-(

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

怂人 2024-08-31 10:40:57

因为decimal模块不与除long、int和Decimal之外的任何类型进行比较。在所有其他情况下,小数会默默地返回“它不知道对象的某些信息”作为更大的值。您可以在十进制的 _convert_other() 函数中看到这种行为。

愚蠢的 Decimal 类。

哦,另请参阅http://bugs.python.org/issue2531。 em>

因此,会发生以下情况:

  • 解释器调用 Decimal.__gt__ 比较函数。
  • Decimal.__gt__ 调用 Decimal._convert_other 将传入的浮点数转换为 Decimal。
  • Decimal._convert_other 不理解浮点数。 Decimal._convert_other 中的实现
    显式检查操作数的 longintDecimal 类型。是的,这是
    一个错误,因为意外的库实现会导致进一步的错误。它
    做正确的事情甚至只是通过 TypeException 会更干净。反而
    它会经历与将 Decimal 与其他内容进行比较时相同的 NotImplemented
    员工记录的哈希值。
  • 尝试了一些其他比较操作。比较放弃。
  • 调用 CPython 的 Objects/object.c/default_3way_compare 中的默认比较。
  • 在 Python 3 中,这确实令人呕吐。在 Python 2 中,它比较 id() 函数。
  • 在 Windows 上,使用(某种程度上)不区分大小写的比较。在现代系统上,
    使用区分大小写的比较。
  • 所以你会得到不同的结果。

我们到了吗?

Because the decimal module does not compare against any type except long, int, and Decimal. In all other cases, decimal silently returns the "not something it knows about object" as greater. You can see this behavior in the _convert_other() function of decimal.py

Silly, silly Decimal class.

Oh, see http://bugs.python.org/issue2531 as well.

So, here is what happens:

  • The interpreter calls the Decimal.__gt__ comparison function.
  • Decimal.__gt__ calls Decimal._convert_other to convert the incoming float to a Decimal.
  • Decimal._convert_other doesn't understand floats. The implementation down in Decimal._convert_other
    explicitly checks for long, int, and Decimal types of the operand. Yes, this is
    a bug, in that unexpected library implementations cause bugs further down the line. It
    would be cleaner to do the right thing or even just through a TypeException. Instead
    it throughs the same NotImplemented that would happen comparing a Decimal to, say,
    a hash of Employee records.
  • A few other comparison operations are tried. Comparison gives up.
  • The default comparison, down in CPython's Objects/object.c/default_3way_compare get called.
  • In Python 3, this rightly barfs. In Python 2, it compares the id() functions.
  • On Windows, a case insensitive comparison is used (sort of). On modern systems, a
    case sensitive comparison is used.
  • So you get different results.

Are we there yet?

暖阳 2024-08-31 10:40:57
def __gt__(self, other, context=None):
    other = _convert_other(other)
    if other is NotImplemented:
        return other
    ans = self._compare_check_nans(other, context)
    if ans:
        return False
    return self._cmp(other) > 0


def _convert_other(other, raiseit=False):
    """Convert other to Decimal.

    Verifies that it's ok to use in an implicit construction.
    """
    if isinstance(other, Decimal):
        return other
    if isinstance(other, (int, long)):
        return Decimal(other)
    if raiseit:
        raise TypeError("Unable to convert %s to Decimal" % other)
    return NotImplemented
def __gt__(self, other, context=None):
    other = _convert_other(other)
    if other is NotImplemented:
        return other
    ans = self._compare_check_nans(other, context)
    if ans:
        return False
    return self._cmp(other) > 0


def _convert_other(other, raiseit=False):
    """Convert other to Decimal.

    Verifies that it's ok to use in an implicit construction.
    """
    if isinstance(other, Decimal):
        return other
    if isinstance(other, (int, long)):
        return Decimal(other)
    if raiseit:
        raise TypeError("Unable to convert %s to Decimal" % other)
    return NotImplemented
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文