lua語言---浮點數轉16進制

--這個版本,經過驗證 ,可把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))
--]]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章