设计一个函数把两个数字相加。不得使用 + 或者其他算术运算符。
示例:
输入: a = 1, b = 1
输出: 2
提示:
a, b 均可能是负数或 0
结果不会溢出 32 位整数
解题思路
首先左移和右移的区别是很好区分的
左移<< :就是该数对应二进制码整体左移,左边超出的部分舍弃,右边补零。举个例子:253的二进制码1111 1101,在经过运算253<<2后得到1111 0100。很简单
右移>> :该数对应的二进制码整体右移,左边的用原有标志位补充,右边超出的部分舍弃。
无符号右移>>> :不管正负标志位为0还是1,将该数的二进制码整体右移,左边部分总是以0填充,右边部分舍弃。
举例对比:
-5用二进制表示1111 1011,红色为该数标志位
-5>>2: 1111 1011-------------->1111 1110。
11为标志位
-5>>>2: 1111 1011-------------->0011 1110。
00为补充的0
总结
<< 左移:向左移动2的倍数,就是乘以2的移动的位数次幂
>> 右移:向右除以2的移动位数次幂
>>>无符号右移:无论最高位是什么 ,右移后,都补0;而>>右移补0还是补1由最高位确定。
python 由于不知道符号位具体是第几位,因此需要进行的操作是
将输入数字转化成无符号整数
计算无符号整数相加并的到结果
讲结果根据范围判定,映射为有符号整型
class Solution:
def add(self, a: int, b: int) -> int:
a &= 0xFFFFFFFF
b &= 0xFFFFFFFF
while b != 0:
carry = a & b
a ^= b
b = ((carry) << 1) & 0xFFFFFFFF
return a if a < 0x80000000 else ~(a^0xFFFFFFFF)
为什么要和 oxffffffff 作与运算
一般来讲,整形数在内存中是以 补码 的形式存放的,输出的时候同样也是按照 补码 输出的。
但是在 Python 中,情况是这样的:
整形是以 补码 形式存放的,输出的时候是按照 二进制 表示输出的;
对于 bin(x)bin(x)bin(x)(xxx 为 十进制负数),输出的是它的原码的二进制表示加上一个负号,方便查看(方便个🔨🔨🔨)
对于 bin(x)bin(x)bin(x)(xxx 为 十六进制负数),输出的是对应的二进制表示。
所以为了获得十进制负数的补码,我们需要手动将其和 0xffffffff 进行与操作,得到一个十六进制数,再交给 bin() 转化,这时内存中得到的才是你想要的补码。
考研对信息的获取至关重要,此公众号会发表计算机考研(初复试信息)、夏令营等资料,方便考研人对信息的获取,节约自身查找资料的时间