補碼
正數補碼是本身,
負數補碼是 符號位不變,其餘逐位求反再加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