1.简介
该篇博客主要阐述如何将按16进制存储的32位浮点数字符串转换为十进制数
数据示例如下:
‘3f cc 00 00’ -> 1.59375 'ff 7f ff ff' -> -3.40282346639e+38
‘41 a4 c0 00’ -> 20.59375
注:这里的字节序按照大端法;小端法需要增加一行代码(已经表明)
2.原理
顾名思义,32位浮点数共计32位,有三个组成部分:符号位S、阶码E、尾数M。S、E、M所占位数分别为1、8、23位。
注释:S表示正负(0为正,1为负);E用移码表示(偏移量为127);M不足23位时右端补0
正向推理:
已知十进制数20.59375,它的二进制形式为 10100.10011,移动小数点位置10100.10011=1.010010011×24
注:移动小数点是移动到整数位是1就停止,此时为左移; 也可能右移,例如 0.59375 = 0.10011 = 1.0011 x 2-1
1.符号位S:
该十进制数为正,S = 0
2.阶码E:
指数为4,加上偏移量127后为131,转换为2进制数 E = 1000 0011
3.尾数M:
尾数为小数部分,当位数不足23位时用0补齐 M = 010 0100 1100 0000 0000 0000
4.32位浮点数:
S+E+M -> 0 1000 0011 010 0100 1100 0000 0000 0000
将32位浮点数转换为16进制:
01000001 10100100 11000000 00000000 -> 41 a4 c0 00
逆向推理:
已知‘41 a4 c0 00’,将它转换为十进制数
第一步:变为二进制
41 a4 c0 00 -> 01000001 10100100 11000000 00000000
第二步:取S、E、M
S = 0
E = 1000 0011
M = 010 0100 1100 0000 0000 0000
第三步:公式计算
32位浮点数 = (-1)^S * (1+M10) * 2^E10
指数 E10 = (E)10 - 127 = (1000 0011)10 - 127 = 4
十进制浮点小数 M10 = (0.M)10 = (0.0100 1001 1)10= 0.287109375
32位浮点数 = (-1)^S * (1+M10) * 2^E10
则32位浮点数 = (-1)^0 * (1 + 0.287109375) * 2^4 = 20.59375
3.代码
'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def hextonum(string):
# 16进制转2进制
num_2 = ''
new_list = str(string).strip().split(' ')
# new_list.reverse() # 如果使用小段法,则需要增加该行代码
for l in new_list:
temp = bin(int(l, 16))[2:]
if len(temp) != 8:
temp = '0' * (8 - len(temp)) + temp
num_2 = num_2 + temp
# 符号位、阶码、尾数
s2 = num_2[0]
e2 = num_2[1:9]
m2 = num_2[9:]
print s2, e2, m2
# 计算小数部分(10进制)
if len(m2) != 0:
temp = 0
for i in range(1, len(m2)+1):
temp = temp + int(m2[i - 1]) * (2 ** (-1 * i))
latter10 = temp
else:
latter10 = 0
print latter10
# 计算阶数
e10 = int(e2, 2) - 127
# 计算公式
num_10 = ((-1)**int(s2))*(1 + latter10)*(2**e10)
return num_10
s = '41 a4 c0 00'
print hextonum(s)
print (-1)**0 * (1+0.287109375) * (2**4)
结果如下:
0 10000011 01001001100000000000000
0.287109375
20.59375
20.59375