在Python 3中使用按位运算添加两个整数时的无限循环

Infinite loop while adding two integers using bitwise operations in Python 3

我正试图解决一个问题,那就是编写python代码,在不使用"+"或"-"运算符的情况下添加两个整数。我有以下两个正数的代码:

1
2
3
4
5
6
7
8
9
def getSum(self, a, b):

    while (a & b):
        x = a & b
        y = a ^ b
        a = x << 1
        b = y

    return a ^ b

如果输入是两个正整数或两个负整数,则此代码非常适用,但当一个数字为正,另一个为负时,此代码将失败。它进入无限循环。你知道为什么会这样吗?


python 3具有任意精度整数("bignums")。这意味着,只要x为负数,x << 1就会使x为负数,其大小是原来的两倍。从右边移入的零只会使数字越来越大。

在two的补码中,正数的最高位是0,负数的最高位是1。这意味着,当ab中只有一个为负时,ab的顶位将不同。因此,x为正(1 & 0 = 0),y为负(1 ^ 0 = 1)。因此,新的a将是正的(x<<1),新的b将是负的(y)。

现在:任意精度的负整数实际上有无限多的前导1位,至少在数学上是这样。因此,a是一个越来越大的正数,每次迭代扩展2次。b不断地得到越来越多的前导1位,增加这些位可以执行&^的位。因此,无论a的位与b的一个相加的1位对齐,因此a & b始终为真,因此循环将永远运行。


我猜这是一个家庭作业问题,所以我不想只给你一个有用的功能——你会通过努力学习更多。

这个问题源于负整数的存储方式。为了便于说明,让我们假设您处理的是4位有符号整数(而不是32位有符号整数或其他)。数字+1是0001。数字-1是1111。你应该能够坐下来用笔和纸,并用这两个数字手动运行你的功能。当然,答案应该是0000,但我认为通过使用笔和纸处理这个简化的案例,您会发现代码出了什么问题。