找回密码
 register

QQ登录

只需一步,快速开始

查看: 96|回复: 0

[游戏教程] 使用LUA 5.1 实现 IEEE754算法

[复制链接]

[游戏教程] 使用LUA 5.1 实现 IEEE754算法

[复制链接]
  • 打卡等级:热心大叔
  • 打卡总天数:95
  • 打卡月天数:18
  • 打卡总奖励:95
  • 最近打卡:2025-01-20 23:11:04
Waylee

主题

0

回帖

1万

积分

仙帝

积分
12398
Waylee 2024-2-18 16:38 | 显示全部楼层 |阅读模式

马上注册,查看网站隐藏内容!!

您需要 登录 才可以下载或查看,没有账号?register

×
注意存在一定的误差
十六进制的HEX字符串 转换成 浮点数

function hexToFloat( hexString )
        if hexString == nil then
                return 0
        end
        local t = type( hexString )
        if t == "string" then
                hexString = tonumber(hexString , 16)
        end
 
        local hexNums = hexString
 
        local sign = math.modf(hexNums/(2^31))
 
        local exponent = hexNums % (2^31)
        exponent = math.modf(exponent/(2^23)) -127
 
        local mantissa = hexNums % (2^23)
 
        for i=1,23 do
                mantissa = mantissa / 2
        end
        mantissa = 1+mantissa
--        print(mantissa)
        local result = (-1)^sign * mantissa * 2^exponent
        result = tonumber(string.format('%.3f', result))
        return result
end



浮点数转换成 十六进制字符串

function floattohex(floatNum)
        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(floatNum > 0)then
                S = 0
        else        
                S = 1
        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



用30000组数据测试数据的正确性

for i= 1,30000 do
        num = 0;
        --math.randomseed(os.time())
        num = tonumber(string.format('%.3f', math.random() + math.random(0,10) ))
         num_result = num;
        print("i = " .. i.. " num :" .. num_result )
        str_hex = floattohex(num_result)
        num_str =hexToFloat(str_hex)
        if(num_result == tonumber(num_str))then
                --print("i = " .. i.. "  对比正确true")
        else
                print("对比错误false")
        end
        --print("**************************************************")
end



您需要登录后才可以回帖 登录 | register

本版积分规则

雪舞知识库 | 浙ICP备15015590号-1 | 萌ICP备20232229号|浙公网安备33048102000118号 |天天打卡

GMT+8, 2025-1-21 02:52 , Processed in 0.097348 second(s), 8 queries , Redis On.

Powered by XueWu Licensed

Copyright © Tencent Cloud.

快速回复 返回顶部 返回列表