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

时间:2016-08-24 02:27:39

标签: python python-3.x bit-manipulation bitwise-operators

我正在尝试解决一个问题,即编写python代码以添加两个整数而不使用' +'或者' - '运营商。我有以下代码,它适用于两个正数:

def getSum(self, a, b):

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

    return a ^ b

这段代码完美适用于输入是两个正整数还是两个负整数但是当一个数字为正数而另一个数字为负数时失败。它进入无限循环。知道为什么会这样吗?

2 个答案:

答案 0 :(得分:7)

Python 3有arbitrary-precision integers ("bignums")。这意味着,只要x为负数,x << 1就会使x为负数,其幅度为两倍。从右侧移入的零将使数字越来越大。

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

现在:任意精度负整数实际上具有无限数量的前导1位,至少是数学上的。所以a是一个越来越大的正数,每次迭代扩展2。 b不断添加越来越多的前导1位,以便能够使用&执行按位^a。因此,a的任何位都与1的{​​{1}}位之一一致,因此b始终为真,因此循环将永远运行。

答案 1 :(得分:0)

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

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