首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lua - packing IEEE754单精度浮点数

Lua - packing IEEE754单精度浮点数
EN

Stack Overflow用户
提问于 2013-01-19 17:11:45
回答 2查看 2.6K关注 0票数 11

我想在纯Lua中创建一个函数,它从一个数字生成一个分数 (23位)、一个指数 (8位)和一个符号 (1位),这样这个数字大约等于math.ldexp(fraction, exponent - 127) * (sign == 1 and -1 or 1),然后将生成的值打包成32位。

数学图书馆中的一个特定功能引起了我的注意:

frexp函数将浮点值(v)分解为尾数(m)和指数(n),使得m的绝对值大于或等于0.5,小于1.0,v=m* 2^n。 注意,math.ldexp是逆操作。

但是,我想不出有什么方法可以正确地打包非整数.由于这个函数返回的尾数不是整数,所以我不确定是否可以使用它。

是否有任何有效的方法来执行类似于math.frexp()的操作,后者将整数作为尾数返回?或者,是否有更好的方法将数字以Lua中的IEEE754单精度浮点格式打包?

提前谢谢你。

编辑

我在此提出(希望)我所做的功能的最终版本:

代码语言:javascript
复制
function PackIEEE754(number)
    if number == 0 then
        return string.char(0x00, 0x00, 0x00, 0x00)
    elseif number ~= number then
        return string.char(0xFF, 0xFF, 0xFF, 0xFF)
    else
        local sign = 0x00
        if number < 0 then
            sign = 0x80
            number = -number
        end
        local mantissa, exponent = math.frexp(number)
        exponent = exponent + 0x7F
        if exponent <= 0 then
            mantissa = math.ldexp(mantissa, exponent - 1)
            exponent = 0
        elseif exponent > 0 then
            if exponent >= 0xFF then
                return string.char(sign + 0x7F, 0x80, 0x00, 0x00)
            elseif exponent == 1 then
                exponent = 0
            else
                mantissa = mantissa * 2 - 1
                exponent = exponent - 1
            end
        end
        mantissa = math.floor(math.ldexp(mantissa, 23) + 0.5)
        return string.char(
                sign + math.floor(exponent / 2),
                (exponent % 2) * 0x80 + math.floor(mantissa / 0x10000),
                math.floor(mantissa / 0x100) % 0x100,
                mantissa % 0x100)
    end
end
function UnpackIEEE754(packed)
    local b1, b2, b3, b4 = string.byte(packed, 1, 4)
    local exponent = (b1 % 0x80) * 0x02 + math.floor(b2 / 0x80)
    local mantissa = math.ldexp(((b2 % 0x80) * 0x100 + b3) * 0x100 + b4, -23)
    if exponent == 0xFF then
        if mantissa > 0 then
            return 0 / 0
        else
            mantissa = math.huge
            exponent = 0x7F
        end
    elseif exponent > 0 then
        mantissa = mantissa + 1
    else
        exponent = exponent + 1
    end
    if b1 >= 0x80 then
        mantissa = -mantissa
    end
    return math.ldexp(mantissa, exponent - 0x7F)
end

我改进了使用隐式位的方法,并添加了对特殊值(如NaN和无穷大)的适当支持。我基于与catwell链接的脚本的格式设置。

我感谢你们两位的好建议。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-01-19 17:14:26

将从math.frexp()中得到的意义乘以2^ 24,再从指数中减去24进行补偿。现在意义是一个整数。请注意,意义是24位,而不是23位(您需要考虑IEEE-754编码中的隐式位)。

票数 7
EN

Stack Overflow用户

发布于 2013-01-21 09:48:14

你见过吗?

我认为它以一种轻巧、简单的方式实现了你想要的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14416734

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档