经常遇到对二进制字符串进行原码和补码转换,便写个函数记录一下。
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
。