采用递归思想: 虽然s = a + b = n + c,但是n + c还是用了'+',因此我们对n + c再次采用这种运算 (也就是把n当成a,c当成b,继续做a+b运算。看似无限循环,但是进位c总会有等于0的时候,此时结果就等于n)。
非递归同理,循环求n和c,直至进位c = 0; 此时s = n, 返回n即可。
class Solution:
def add(self, a: int, b: int) -> int:
x = 0xffffffff
a, b = a & x, b & x # python中将python存储补码的形式转换为32位有符号数的补码形式,用另一个数字表示出来
while b:
a, b = a ^ b, (a & b) << 1 & x
return a if a <= 0x7fffffff else ~(a ^ x) # 将一个数的32位有符号数的补码形式转换为python存储的补码形式
if __name__ == '__main__':
solution = Solution()
a, b = -5, 6
a, b = 2147483646, 1
res = solution.add(a, b)
print(res)
补充:
Python 负数的存储:
Python,Java, C++ 等语言中的数字都是以 补码 形式存储的。但 Python 没有 int , long 等不同长度变量,即在编程时无变量位数的概念。
获取负数的补码: 需要将数字与十六进制数 0xffffffff 相与。可理解为舍去此数字 32 位以上的数字(将 32 位以上都变为 000 ),从无限长度变为一个 32 位整数。
返回前数字还原: 若补码 dataA 为负数( 0x7fffffff 是最大的正数的补码 ),需执行 ~(dataA ^ x) 操作,将补码还原至 Python 的存储格式。dataA ^ x 运算将 1 至 32 位按位取反;~ 运算是将整个数字取反;因此,~(dataA ^ x) 是将 32 位以上的位取反,1 至 32 位不变。
print(hex(1)) # = 0x1 补码
print(hex(-1)) # = -0x1 负号 + 原码 ( Python 特色,Java 会直接输出补码)
print(hex(1 & 0xffffffff)) # = 0x1 正数补码
print(hex(-1 & 0xffffffff)) # = 0xffffffff 负数补码
print(-1 & 0xffffffff) # = 4294967295 ( Python 将其认为正数)