--这个版本,经过验证 ,可把16进制,转浮点数,验证时间 2018-5-28 23:02
--[[
0.0001 38D1B717
-0.0001 B8D1B717
178.125 43322000
20.59375 41A4C000
-1.275 BFA33332
0.125 3E000000
-0.65 BF266666
0.75 3F400000
0.5 3F000000
0.6 3F199999
0.7 3F333333
0.8 3F4CCCCC
0.9 3F666666
--]]
--鍔熻兘锛氭妸4涓瓧鑺傜殑16杩涘埗锛岃浆鎹㈡垚锛屾诞鐐规暟锛屽苟鎵撳嵃鍑烘潵
function DatToFloat1(x)
local temp
local aa = 8388608
s = (x&0x80000000)>>31
e = (x&0x7F800000)>>23
temp = (x&0X7FFFFF)/aa
--print(s, e, temp)
local res = (1<<(e-127)) (1+temp)
--local res = (1<<math.abs(e-127)) (1+temp)
if s==1 then res = 0-res end
return res
end
--璁$畻2 鐨?-n 娆℃柟
function pow(n)
local temp =1
for m =1, n do
temp = temp * 0.5
end
return temp
end
--鐢ㄤ簬璁$畻灏忎簬
function DatToFloat2(x)
--print("DatToFloat2")
s = (x&0x80000000)>>31
e = (x&0x7F800000)>>23
--print("e "..e)
m = 127-e
temp = pow(m)
local weishu = x & 0x7FFFFF
--璁$畻灏炬暟閮ㄥ垎鐨勫€?
local sum = 0
local j = 23+m
local weishutemp = weishu ~ (0x1<<23)
for m = 1 , 24 do
bitdat = weishutemp & 0x1
if bitdat == 1 then sum = sum + pow(j) end
weishutemp = weishutemp >>1
j = j -1
end
--print("sum = "..sum)
if s==1 then sum = 0-sum end
return sum
end
function DatToFloat(x)
local result
local e = (x&0x7F800000)>>23
if e==255 and (x&0x7FFFFF) == 0 then return "InF" end
if e==255 and (x&0x7FFFFF) ~= 0 then return "NaN" end
if e>=128 then
result = DatToFloat1(x)
else
result = DatToFloat2(x)
end
return result
end
function FloatToDat(x)
local srcDat = x
x = math.abs(x)
local x1 = math.floor(x) --整数部分
local x2 = x- x1 --小数部分
--print(x1, x2)
local bitNumb_x1 = 1 --整数部分占的bit数
local bitNumb_x2 --小数部分占的bit数
local offset --当输入为小于1的时候,指数部分
local fracValue --小数部分的值
local res
--求整数X1有多少BIT
local temp = x1
while(true) do
res = temp >> 1
if res == 0 then break
else bitNumb_x1 = bitNumb_x1 +1
end
temp = temp >>1
end
--print("bitNumn "..bitNumb_x1)
--计算出小数部分的值
if x < 1.0 then flag = 1 else flag = 0 end --0表示 <1.0 的运算 , 1表示大于1.0
fracValue, bitNumb_x2, Offset = Frac2( x2,bitNumb_x1, flag )--得到小数部分的十进制值,和该值占了多少个bit
--print("envoke done:", fracValue, nbit2, Offset)
local tt = x1 & ((1<<(bitNumb_x1-1)) -1) --把最高bit,置 0
local res1 = (tt<<bitNumb_x2) ~ fracValue -- 314572 = 1001 1001 1001 1001 100
local res2 = res1<<(24 - bitNumb_x2 - bitNumb_x1)
--print(nbit2, bitNumb, 24-nbit2-bitNumb+1)
--print("tt ="..tt)
--print("res1 = "..res1)
-- print("res2 = "..res2)
--print(23-nbit2-bitNumb-1)
--计算指数部分
e = 127 + bitNumb_x1 - 1
if math.abs(srcDat) < 1.0 then e =127 - Offset end
--计算出最后的结果:指数部分 和 尾数部分
local result = (e<<23) ~ res2
--如果是负数 ,最高位要设置成 1
if srcDat < 0 then result = result ~ 0x80000000 end
return result
end
--返回值 十进制数值,以及对应的2进制占了多少bit, 指数偏移
--输入:
-- 小数部分
-- 以及对应的浮点数整数部分占的bit数
-- 大于 1.0 标记,如果小于 1.0 应该传1.否则传0
function Frac2(x, bitNumb, flag)
local reslist = {}
m = 1
quitFlag = 0
local next
local Limit --小数部分转换的最大bit数
--local Limit = 23 - bitNumb --因为最大23bit, 前面部分是整数占的宽度, 所以这里小数部分位宽要限制
--local Limit = 24 - bitNumb
if flag==1 then
--Limit = 26 - bitNumb --print("limit "..Limit.." "..bitNumb)
--Limit = 38 - bitNumb
Limit = 44 - bitNumb
else Limit = 23 - bitNumb
end
--把小数部分, 转换成2进制,存到reslist表里面
while true do
temp = x*2
if temp == 1.0 then reslist[m] = 1 break end
if temp >1.0 then next = temp -1.0 else next = temp end
if temp > 1.0 then reslist[m] = 1 else reslist[m] = 0 end
if m >=Limit then break end
x = next
--print(next)
--print(temp)
m = m + 1
end
local nLen = (#reslist) --小数部分占的BIT数
local sum = 0 --小数部分的值
--如果是大于1 的浮点数,计算其小数部分的值
if flag == 0 then
local j = (#reslist) -1
if nLen == 0 then
sum = sum + reslist[1]
else
for i, e in pairs(reslist) do
sum = sum + (reslist[i] << j)
j = j -1
--print (i, e)
end
end
end
--如果是小于1 的浮点数,计算其小数部分的值
local src_index = 0 --指数部分的偏移值
if flag==1 then
-- debug
--for i, e in pairs(reslist) do
--print (i, e)
--end
--]]
for m = 1, (#reslist) do
if reslist[m] == 1 then src_index = m break end
end
local tmp = (#reslist) - src_index
if tmp~= 0 then
j = tmp -1
sum = 0
for m = src_index+1 , (#reslist) do
sum = sum + (reslist[m] << j)
--print(m, reslist[m] )
j = j -1
end
else
sum = 0
end
nLen = tmp
--print("src_index= "..src_index)
--print("nLen = "..nLen)
--print("sum = "..sum)
reslist = nil
return sum, nLen, src_index
end
reslist = nil
return sum, nLen
end
--
TestDatArray = {-0.023676, -0.0001, 178.125, 20.59375 ,-1.275, 0.125, -0.65, 0.75, 0.5, 0.6,0.7, 0.8,0.9}
--TestDatArray = {0.75, -2.5, -2.5, 0.123, 178.125, 20.59375, -180.5 }
--TestDatArray = { 0.75, 0.2, 0.3, 0.4, 0.5, 0.6,0.7,0.8}
print"**"
local file = io.open("IEEE754.txt","w")
local str
for m = 1 , 13 do
rr = FloatToDat(TestDatArray[m])
str = tostring(TestDatArray[m])..(string.format(" %08X\n", rr))
file:write( str)
end
file:close()
--]]
--[[
y = FloatToDat(3.4)
print(string.format("0X %08X",y))
--]]
来源:51CTO
作者:2120110819
链接:https://blog.51cto.com/14018328/2476842