python 負數補碼存儲問題

補碼

正數補碼是本身,

負數補碼是 符號位不變,其餘逐位求反再加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. 不用加減乘除做加法

參考:

【1】https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/

【2】https://blog.csdn.net/qinglv1/article/details/90580013

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章