参考文档:
【1】https://blog.csdn.net/weixin_30597089/article/details/113040138?spm=1001.2014.3001.5506
【2】https://blog.csdn.net/weixin_43142607/article/details/123376774
对于C/C++就很简单了,直接定义一个联合体即可将浮点转成十六进制,需要注意的是,在STM32上面是使用小端模式,因此存储是先存高位。例如0x12345678,应该依次存储0x78,0x56,0x34,0x12。
最近项目上面需要做一个自动化平台,脚本使用lua语言,其中用到了浮点型转16进制, 网上参考了许多资料,但是没有能够直接使用的。找到链接2的文章,修改了不能转负数的问题,其实就是 负数求绝对值,然后改变一下符号位。测试后应该是能够使用了。
事先说明,本人不是从事上位机开发的,如有问题请指出。因此直接贴代码不分析。
参考链接1,浮点型的存储方式主要分为三部分:
- 符号位S,占最高位1位,正数为0,负数为1
- 指数位E,占MSB-1开始的8位,指的是小数点移动的尾数,移动后必须保证整数位为1。且小数点左移为正,小数点右移为负,没有移动即为0 。为了存储负数,制定了偏移量为127,即最终值E=127+移动位数。
这里有些同学的程序容易出错误在处理小于1大于-1的数,因此我没有采用这些参考程序。 - 尾数位M,单精度占23位,指移动小数点后的尾数。需要说明的是,是二进制的尾数。
function floattohex(floatNum)
--add by radar begin
local flag = 0
if(floatNum < 0)then
flag = 1
floatNum=math.abs(floatNum)
end
--add by radar end
if(floatNum == 0)then
return 0;
end
---给一个浮点数 33.758
--1.将浮点数分成整数和小数
num_z,num_x= math.modf(floatNum/1)
--print("整数:" .. num_z .. " 小数:".. num_x)
--2.将整数部分化成二进制
str_z = ""
intercount = 0; --转换成二进制一共多少位
num1 = num_z
if(num1 == 0)then
intercount = 0
str_z = "0"
else
repeat
num = num1
num1= math.modf(num1/2)
num2 = num - num1*2
intercount = intercount + 1 --阶乘
str_z = str_z .. num2
until (num1 == 0)
end
str_z = string.reverse(str_z)
--print("整数:" .. str_z)
--3.将小数转换成二进制
str_x = ""
num2 = num_x
repeat
num2 = num2 *2
num1,num2 = math.modf(num2/1)
str_x = str_x .. num1
until(num2 == 0 or #str_x >=40)
--print("小数:"..str_x)
--4.浮点数的二进制表示
--print("浮点数的二进制表示 :" .. str_z .. "." .. str_x)
--浮点数的二进制表示 :一种:0.00110101110000101000111
--两种:1011.01101011100001010
--5.首先确认整数是否大于0,
--(1)==0 右移 查找小数二进制何时有1
--(2) >0 左移
e = 0
str_m =""
if(num_z == 0)then
num_1 =string.find(str_x,"1") --阶
e = -num_1
str_m = string.sub(str_x,num_1+1,-1)
else
e = intercount - 1
str_m = string.sub(str_z,2,-1) .. str_x
end
--??考虑str_m是否有23位
if(#str_m ~= 23)then
if(#str_m > 23)then
str_m = string.sub(str_m,1,23)
end
if(#str_m <23)then
len_m = 23 - #str_m
for i = 1,len_m do
str_m = str_m .."0"
end
end
end
M = str_m
--print("M = " .. M)
--考虑把它转换成二进制
E = e + 127
str_e = "" --E的二进制
intercount_e = 0
num1 = E
repeat
num = num1
num1= math.modf(num1/2)
num2 = num - num1*2
intercount_e = intercount_e + 1 --阶乘
str_e = str_e .. num2
until (num1 == 0)
if(#str_e ~= 8)then
len_e = 8 - #str_e
for i = 1,len_e do
str_e = str_e .."0"
end
end
E = string.reverse(str_e)
--print("E的二进制字符串:" .. E)--此时str_e 是E的二进制字符串
--6.确定 S
if(flag ==1)then
S = 1
else
S = 0
end
--print("S:" .. S)
--7.将S E M 二进制转换
str = S .. E .. M
result = string.format("%08X",tonumber(str,2))
--print ("result =" .. result)
--print("**************************************************")
return result;
end
print(floattohex(-0.000202))