--这个版本,经过验证 ,可把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))
--]]