gpt4 book ai didi

python - 为什么 9007199254740993 != 9007199254740993.0?

转载 作者:太空狗 更新时间:2023-10-29 21:42:44 24 4
gpt4 key购买 nike

这个比较的结果让我很吃惊(CPython 3.4):

>>> 9007199254740993 == 9007199254740993.0
False

我对the docs的理解是左操作数应该转换为 float 以匹配右操作数的类型:

Python fully supports mixed arithmetic: when a binary arithmetic operator has operands of different numeric types, the operand with the “narrower” type is widened to that of the other, where integer is narrower than floating point, which is narrower than complex. Comparisons between numbers of mixed type use the same rule. The constructors int(), float(), and complex() can be used to produce numbers of a specific type.

这似乎并没有发生:

>>> float(9007199254740993) == 9007199254740993.0
True

这是怎么回事?

最佳答案

Python 并没有准确地在这里将整数转换为 float ;它将 float 转换为整数:

>>> 9007199254740993 == int(9007199254740993.0)
False

失败是因为 int(9007199254740993.0) 实际上是 9007199254740992:

>>> 9007199254740992 == 9007199254740993.0
True

参见 float_richcompare() function .具体来说,它前面的评论:

/* Comparison is pretty much a nightmare. 

[...]

* When mixing float with an integer type, there's no good *uniform* approach.
* Converting the double to an integer obviously doesn't work, since we
* may lose info from fractional bits. Converting the integer to a double
* also has two failure modes: (1) an int may trigger overflow (too
* large to fit in the dynamic range of a C double); (2) even a C long may have
* more bits than fit in a C double (e.g., on a 64-bit box long may have
* 63 bits of precision, but a C double probably has only 53), and then
* we can falsely claim equality when low-order integer bits are lost by
* coercion to double. So this part is painful too.

这两个数字会发生什么:

  • Python 尝试 int.__eq__(float) 路由,但返回 NotImplemented
  • Python 尝试 float.__eq__(int) 路由,由 float_richcompare() 处理。

在该函数中,v 是您的 float ,w 是整数。以下是为该路径执行的代码选择:

else if (PyLong_Check(w)) {   /* true because the other number is an Python integer */

/* ... */

nbits = _PyLong_NumBits(w); /* 54 for your integer */

/* ... */

if (nbits <= 48) { /* nope, can't make it a float outright */
/* ... */
}

(void) frexp(i, &exponent); /* the exponent is 54 for your float */

if (exponent < 0 || (size_t)exponent < nbits) {
/* not true */
}
if ((size_t)exponent > nbits) {
/* also not true */
}
/* v and w have the same number of bits before the radix
* point. Construct two ints that have the same comparison
* outcome.
*/
{
/* code to convert v to an integer vv, copy w to ww */

r = PyObject_RichCompareBool(vv, ww, op);

/* ... */

result = PyBool_FromLong(r);

/* ... */

return result;
}

所以最后由于所涉及的数字的大小,Python 将 float 转换为整数,也就是 float 转换为 9007199254740992。这是因为 float 实际上不能准确地表达 9007199254740993.0:

>>> 9007199254740993.0
9007199254740992.0

关于python - 为什么 9007199254740993 != 9007199254740993.0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31437463/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com