补码
正数补码是本身,
负数补码是 符号位不变,其余逐位求反再加1。
相加减运算规则(a+b):
(1) a ->补码a b -> 补码b
(2)按位相加,将第一位舍弃
(3)补码还原【原码就是补码的补码】
具体二进制补码问题,详见 ->https://blog.csdn.net/zhuozuozhi/article/details/80896838;链接2
python中负数补码
python中的正负数[正数]都是以补码的形式存在的。
在c中负数直接使用补码的方式存储的[用2的补码的方式表示负数],但是在python中 是用原码+'-'产生的。而且十进制、十六进制下的负数表示不同。
a = bin(-3)
print(a)
a = bin(3)
print(a)
b = bin(-3 & 0xffffffff)
print(b)
c = bin(0xfffffffd)
print(c)
//输出
//-0b11
//0b11
//0b11111111111111111111111111111101
//0b11111111111111111111111111111101
为了获得负数(十进制表示)的补码,需要手动将其和十六进制数0xffffffff进行按位与操作,得到结果是个十六进制数,再交给bin()进行输出,得到的才是想要的补码表示。
a = -3
a = bin(-3 & 0xffffffff) # ->十六进制数 => 二进制补码
在涉及到正负数[-30+2]运算的过程中, 应该首先将负数转成补码的形式,即利用 a& 0xffffff[求补],得到二进制负数补码的形式。
再将其与2进行加减运算后,将补码[a+b]进行还原。
还原:先将 (a+b)^0xffffffff [按位取反],再整体取反 ~(a&0xffffff)。将 32 位以上的位取反,即由 0变为 1,1 至 32 位不变。[补码是变过去了,再变回来的一种操作]
a = -30
print(bin(a)) # -0b11110
b = 0b10
# print(bin(a)+b) ##error
b = 2
print(bin(a+b)) ## -0b11100
print(bin(a& 0xffffff)) #16777186 0b111111111111111111100010 ##求补
print(bin ((a&0xffffff)+b)) # 16777188 0b111111111111111111100100 -> 加完之后补码形式
c = (a&0xffffff)+b #补码相加之后的结果
print( ~(c^0xffffff)) # -28 补码还原
print( bin(~(c^0xffffff))) # -28 ->-0b11100
涉及到的题->面试题65. 不用加减乘除做加法。
参考:
【2】https://blog.csdn.net/qinglv1/article/details/90580013