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 |
如果输入是两个正整数或两个负整数,则此代码非常适用,但当一个数字为正,另一个为负时,此代码将失败。它进入无限循环。你知道为什么会这样吗?
- 您对a和b使用哪些测试值?在循环过程中打印或观看a和b的值-它们是否属于重复模式?另外,a还是b是负操作数有区别吗?
python 3具有任意精度整数("bignums")。这意味着,只要x为负数,x << 1就会使x为负数,其大小是原来的两倍。从右边移入的零只会使数字越来越大。
在two的补码中,正数的最高位是0,负数的最高位是1。这意味着,当a和b中只有一个为负时,a和b的顶位将不同。因此,x为正(1 & 0 = 0),y为负(1 ^ 0 = 1)。因此,新的a将是正的(x<<1),新的b将是负的(y)。
现在:任意精度的负整数实际上有无限多的前导1位,至少在数学上是这样。因此,a是一个越来越大的正数,每次迭代扩展2次。b不断地得到越来越多的前导1位,增加这些位可以执行&和^的位。因此,无论a的位与b的一个相加的1位对齐,因此a & b始终为真,因此循环将永远运行。
- 谢谢你的解释。这正是我打印数字时发生的事情。
- 您建议对这段代码进行什么调整来处理这个边缘情况?
- @莫格利啊!这是一个完全不同的问题:)。不过,说真的,我建议你发布一个新问题,链接到这个问题,然后问"如何解决"。我从来没有见过有人抱怨过这样做。所以价值观紧紧围绕着问题,谁知道呢?其他人可能有比我想的更好的解决办法。把这个问题的链接贴在评论里,我来看看。
- @Mowgli我也不会将50%整数对发生的情况描述为"边缘情况"。:)如果必须对其进行调整,我将在函数开始时执行if math.copysign(a,b) != a: raise ValueError("I'm sorry, Dave. I'm afraid I can't do that.")。:)
我猜这是一个家庭作业问题,所以我不想只给你一个有用的功能——你会通过努力学习更多。
这个问题源于负整数的存储方式。为了便于说明,让我们假设您处理的是4位有符号整数(而不是32位有符号整数或其他)。数字+1是0001。数字-1是1111。你应该能够坐下来用笔和纸,并用这两个数字手动运行你的功能。当然,答案应该是0000,但我认为通过使用笔和纸处理这个简化的案例,您会发现代码出了什么问题。
- 欢迎访问本网站,感谢您的回答!我同意通过实践学习是最好的。当你在线的时候,看看这个教程,了解更多关于答案的内容,这个答案很可能会得到加分。享受!
- 谢谢你回答Kloppen。我从来都不想要工作代码。我只是想知道发生了什么。这不是家庭作业问题。:)