二进制概念
- 二进制是用0、1表示的数,计算各种数据在内存中都是0和1组成;
- 一个0 或者 1 表示一位(bit),8bits 为一个字节(byte),内存中最小的存储单元为字节;
- c/c++的int类型一般占用4bytes内存,即4*8=32bits;
- 对于有符号(正、负)的整数,二进制的最高位表示符号位,0表示正数,1表示负数,如:
- 32, 二进制结果->00100000
- -5,二进制结果->10000101
- 65535, 二进制结果->000000001111111111111111
十进制转为二进制
- 使用栈结构,整数除2取余数,倒排列;余数入栈; 最后出栈;
- 也可使用python的bin方法,该方法转出的二进制不是真正的二进制,仍需稍做处理;如bin(30) -> ‘0b11110’;
import math
def int_to_bin(data: int)-> str:
"""
:param data: int
:return: 二进制字符串
使用栈 结构 实现进制的转换 (按照最小存储空间)
"""
if data == 0:
return "0" * 8
# 符号位
symbol_pos = "0" if data >=0 else "1"
# 数据部分的位数
data_bits = math.ceil(math.log2(abs(data)))
total_bits = data_bits + 1 # 数据位 + 符号位
# 总的字节数 (内存中以字节为最小单位)
total_bytes = math.ceil(total_bits / 8)
# 创建一个栈
temp_stack = []
temp = abs(data)
# 整数 除2取余 倒排列 余数入栈
while temp:
val = temp % 2
temp_stack.append(val)
temp = temp // 2
# 出栈
result = ""
while temp_stack:
result += str(temp_stack.pop())
print("二进制的数据位:", result)
# 补0
complement_zero = "0" * (total_bytes * 8 - data_bits - 1)
# 符号位 + 补0位 + 数据位
bin_data = symbol_pos + complement_zero + result
return bin_data
if __name__ == '__main__':
bin_val = int_to_bin(65535)
print("二进制结果:", bin_val)
二进制转为十进制
思路:加权求和,转为十进制
如00011110 转为十进制 ->
1
∗
2
4
+
1
∗
2
3
+
1
∗
2
2
+
1
∗
2
1
+
0
∗
2
0
=
30
{1*2^4 + 1*2^3 + 1* 2^2+1*2^1 + 0*2^0}=30
1∗24+1∗23+1∗22+1∗21+0∗20=30
# 输入一个二进制字符串,返回整数
def bin_to_int(data: str) -> int:
# 符号位
symbol = 1 if data[0] == "0" else -1
# 数据位
data_part = data[1:]
base = len(data_part) - 1
result = 0
for i in data_part:
if i == "1":
result += 1 * 2 ** base
base -= 1
return symbol * result
案例练习
- 将一个无符号(只有非负)整数,转为二进制;
- 翻转该二进制结果,即低八位转为高八位,次低八位转为次高八位,依次类推;
- 将翻转后的二进制,转为十六进制;
- 四位二进制对应一位十六进制;
- 十六进制字符 0-9,A/B/C/D/E/F;
- 如65535转为二进制 000000001111111111111111,翻转后111111111111111100000000,转为十六进制为FFFF00,这里的八位0可以不用,只是用来区分翻转的效果。
import math
def int_to_bin(data: int)-> str:
"""
:param data: 无符号整型,即非负整数
:return: 二进制字符串,没有符号位,只有数据位
这里使用python内置函数bin实现进制的转换 (按照最小存储空间)
"""
if data == 0:
return "0" * 8
# 数据部分的位数
data_bits = math.ceil(math.log2(data))
# 总的字节数 (内存中以字节为最小单位)
total_bytes = math.ceil(data_bits / 8)
# bin转换二进制
bin_data = bin(data) # 0b0011 形式
# 分割二进制数据
bin_data_part = bin_data[2:]
# 补0
complement_zero = "0" * (total_bytes * 8 - data_bits)
# 补0位 + 数据位
bin_data = complement_zero + bin_data_part
# 此时所有位均表示数据
return bin_data
def bin_to_int(data: str) -> int:
# (无符号)二进制中每一位均表示数据
base = len(data) - 1
result = 0
for i in data:
if i == "1":
result += 1 * 2 ** base
base -= 1
# 得到非负数
return result
def reverse_bin_str(data: str) -> str:
"""
:param data: 传入一个二进制字符串
:return: 翻转后的二进制字符串
"""
n = len(data)
result = ""
interval = 8
for i in range(0, n, interval):
result = data[i:i+interval] + result
return result
def bin_to_hex(data: str)-> str:
"""
:param data: 二进制字符串
:return: 十六进制字符串
"""
n = len(data)
interval = 4
region_val = 9
result = ""
for i in range(0, n, interval):
decimal_val = bin_to_int(data[i:i+interval])
hex_char = str(decimal_val) if decimal_val <= region_val else chr(decimal_val % region_val + 64) # A-65 F-70
result += hex_char
return result
if __name__ == '__main__':
bin_val = int_to_bin(65567) # 1F0001
print("二进制结果:", bin_val)
rev_val = reverse_bin_str(bin_val)
print("翻转二进制:", rev_val)
hex_val = bin_to_hex(rev_val)
print("十六进制:", hex_val)