經常遇到對二進制字符串進行原碼和補碼轉換,便寫個函數記錄一下。
def ori2com(ori_str: str):
"""
將原碼字符串 -> 補碼字符串
:param ori_str:原碼字符串
:return:補碼字符串
"""
# 如果符號位爲正,則原碼與補碼相同
if ori_str[0] == '0':
return ori_str
elif ori_str[0] == '1':
value_str = ""
# 數值位按位取反
for i in range(len(ori_str)):
if i == '1':
continue
if ori_str[i] == '0':
value_str += '1'
elif ori_str[i] == '1':
value_str += '0'
# 數值位加 1
n = int(value_str, 2) + 1
com_str = bin(n)[2:]
if len(com_str) >= len(ori_str):
# 說明進位到符號位了
com_str = '0' + com_str[1:]
else:
# 0不夠,中間填充0
n = len(ori_str) - len(com_str) - 1
for i in range(n):
com_str = '0' + com_str
com_str = '1' + com_str
return com_str
def com2ori(com_str: str):
"""
將補碼字符串 -> 原碼字符串
:param com_str: 補碼字符串
:return: 原碼字符串
"""
# 補碼再求一次補碼,就得到原碼
return ori2com(com_str)
def ori2dec(bin_str: str):
"""
將原碼字符串 -> 十進制數值
:param bin_str:原碼字符串
:return:十進制數值
"""
# 如果爲正數
if bin_str[0] == '0':
return int(bin_str, 2)
elif bin_str[0] == '1':
return -int(bin_str[1:], 2)
def com2dec(com_str: str):
"""
將補碼字符串 -> 十進制數值
:param com_str:補碼字符串
:return:十進制數值
"""
ori_str = com2ori(com_str)
return ori2dec(ori_str)
if __name__ == '__main__':
ori_str = '100100100'
print("二進制原碼:" + ori_str)
print("則,")
print('補碼:' + ori2com(ori_str))
print('十進制:', ori2dec(ori_str))
print()
com_str = '100100100'
print("二進制補碼:" + com_str)
print("則,")
print('原碼:' + com2ori(com_str))
print('十進制:', com2dec(com_str))
輸出:
二進制原碼:100100100
則,
補碼:111011100
十進制: -36
二進制補碼:100100100
則,
原碼:111011100
十進制: -220
幾個細節
-
在計算機系統中,數值一律用補碼來表示和存儲。
-
bin()
函數:給一個整數,返回對應正數的原碼字符串。如果是負數的話,會在前面添加一個負號。如給字符串bin(-8)
返回-0b1000
。 -
~
:對數值的補碼按位取反,包括符號位。你看到的(也就是屏幕上顯示的)是十進制數值,如數字5
,但計算機中真正存儲的是該數值的補碼,即0000 0101
(最左邊一位是符號位)。對該補碼進行按位取反得到1111 1010
(符號位也會取反)。輸出顯示時,補碼需轉換成原碼,即得到原碼1000 0110
,再轉換成十進制,即:-6
。 -
int('101', 2)
:將二進制原碼轉化成十進制,默認符號位爲正。如int('101', 2)
返回結果5
。