使用Python中的0xFFFFFFFF掩码检测int32溢出?

9

我发现在Python中使用0xFFFFFFFF掩码可以用于检测int32溢出,但仅适用于正数。

表达式:

x & 0xFFFFFFFF == x

如果 x 没有溢出且 x 大于 0,则返回 True

然而,这个表达式对于负整数不起作用,例如:

(-7 & 0xFFFFFFFF) == -7

将返回False,尽管-7不应溢出int32范围。

有人有关于为什么这种方法对于-7不起作用以及如何使其起作用的想法吗?

1个回答

6
那是因为Python不会考虑数字的任何固定宽度。所以它没有像C/C++语言(最高有效位)那样的符号位。换句话说,当你对负数和0xffff做按位与运算时,结果是一个很大的正数,而不是负数:
>>> print(-7 & 0xFFFF)
65529
>>> print(-7 & 0xFFFFFFFF)
4294967289
>>> 

上述主张的确认:
>>> x = -1
>>> y = -2
>>> z = -4
>>> x.bit_length()
1
>>> y.bit_length()
2
>>> z.bit_length()
3
>>> 

C/C++语言中,由于数字的宽度是固定的,因此:
#include <iostream>
#include <string>

int main()
{
  int i = -7 & 0xFFFFFFFF;
  std::cout <<  i;
}

输出结果是相同的负数(如果我们选择正确的长度放在 & 操作符的右侧)。
-7 

我猜您需要定义一个函数来实现您的目标,并传递具有长度的数字(例如4字节或8字节)。

就像这样:

>>> def isOverflow(num, width=32):
    if num > 0 and num > 2**(width-1) -1 :
        return True
    elif num < 0 and abs(num) > 2**(width-1):
        return True
    return False

或者更高效的版本:

def isOverflow(num, width=32):
    if num > 0:
        if num >> width-1:
            return True
    elif num < 0:
        if abs(num) > (1 << width - 1):
            return True
    return False

以下是其工作原理:
>>> ================================ RESTART ================================
>>> 
>>> isOverflow(-129,8)
True
>>> isOverflow(-128,8)
False
>>> isOverflow(128,8)
True
>>> isOverflow(127,8)
False
>>> isOverflow(0x7fffffff)
False
>>> isOverflow(0x8fffffff)
True

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接