Hex字符串转float(原理及实现-MCGS脚本实现)
1、计算机存储float数据的方法
今天学习了一下HEX和FLOAT互相转换的知识 ,记录一下
计算机存储一个单精度浮点型数据的方法遵循IEEE-754格式标准:
单精度浮点型占据4个字节,用二进制表示占据了32个bit,一个浮点数由3部分组成:符号位s(1位)和、
指数e(8位)、底数m(23位),示意如下:
S E1E2E3E4 E5E6E7E8 M1M2M3 …M 23
2、区分正负
如果 S == 1;这个数是负数,s = -1;否则这个数是正数,s=1。
3、计算指数
e=E1*27+E2*26+E3*25+E4*24+E5*23+E6*22+E7*21+E8*20-(27-1)
4、计算底数
m = M1*2-1+M2*2-2+M3*2-3+…+M24*2-23
注意:如果m值不为0,m=1+m
5、计算float值
f=s*m*2e
6、示例 Hex->Float
HEX 0xBAA137F3 (大端格式)
BIN 1011 1010 1010 0001 0011 0111 1111 0011
S 1 s = -1
e = 0*128 + 1*64 + 1*32 + 1*16 + 0*8 + 1*4 + 0*2 + 1*1 - (128-1) = -10
m=0*1/2+1*1/4+0*1/8+....+1*1/8388608 + 1= 1.259520
f=s*m*2e
= -1*1.259520*2-10
= -1.259520*0.000977
= -0.00123
7、示例 Float->Hex
float -0.00123
符号位 S=1
接下来把 0.00123 分成两部分 整数部分0 和小数部分 0.00123
整数部分转为2进制
0
小数部分转为2进制 0000 0000 0010 10 0001 0011 0111 1111 0011
0.00123*2 = 0.00246 ->0
0.00246*2 = 0.00492 ->0
0.00492*2 = 0.00984 ->0
0.00984*2 = 0.01968 ->0
0.01968*2 = 0.03936 ->0
0.03936*2 = 0.07872 ->0
0.07872*2 = 0.15744 ->0
0.15744*2 = 0.31488 ->0
0.31488*2 = 0.62976 ->0
0.62976*2 = 1.25952 ->0
1.25952*2 = 0.51904 ->1
0.51904*2 = 1.03808 ->0
1.03808*2 = 0.07616 ->1
0.07616*2 = 0.15232 ->0
0.15232*2 = 0.30464 ->0
0.30464*2 = 0.60928 ->0
0.60928*2 = 1.21856 ->0
1.21856*2 = 0.43712 ->1
0.43712*2 = 0.87424 ->0
0.87424*2 = 1.74848 ->0
1.74848*2 = 1.49696 ->1
1.49696*2 = 0.99392 ->1
0.99392*2 = 1.98784 ->0
1.98784*2 = 1.97568 ->1
1.97568*2 = 1.95136 ->1
1.95136*2 = 1.90272 ->1
1.90272*2 = 1.80544 ->1
1.80544*2 = 1.61088 ->1
1.61088*2 = 1.22176 ->1
1.22176*2 = 0.44352 ->1
0.44352*2 = 0.88704 ->0
0.88704*2 = 1.77408 ->0
1.77408*2 = 1.54816 ->1
0.54816*2 = 1.00123 ->1
结合整数部分和小数部分(二进制)
0.0000 0000 0010 10 0001 0011 0111 1111 0011
然后我们用科学计数法来表示(二进制):
0.1010 0001 0011 0111 1111 0011*2^-10
e = -10 根据 计算指数 的方法 反推 EEEE EEEE值(二进制)
EEEE EEEE= 127-10(十进制)
= 117(十进制)
= 75H(十六进制)
= 0111 0101(二进制)
MMM....M = (1)010 0001 0011 0111 1111 0011
由于m 不为0 括号里面的1省略。
MMM....M = 010 0001 0011 0111 1111 0011
组合 S E M 得到
1 0111 0101 010 0001 0011 0111 1111 0011
1011 1010 1010 0001 0011 0111 1111 0011 -> 0xBAA137F3
至此 Float->Hex 转换完毕
8、代码(MCGS脚本 C/C++、JAVA等代码示例很多这里不展示了)
'MCGS 计算单精度浮点数
'
'
'转换为二进制字符串
PrintfData=!I2Bin( !Hex2I(HexIn))
while !len(PrintfData) < 32
PrintfData = "0"+PrintfData
endwhile
HexToFloatSng= !left(PrintfData,1)
if !strComp(HexToFloatSng,"0") <> 0 then '分正负
FloatOut = -1
else
FloatOut = 1
endif
'计算指数(阶码)
HexToFloatE=!mid(PrintfData,2,8)
Hex2FloatE <