ToxicFrog / vstruct

A Lua library for packing and unpacking binary data, supporting arbitrary (byte-aligned) widths, named fields, and repetition.
https://github.com/ToxicFrog/vstruct
Other
109 stars 14 forks source link

Support operation in 5.3 without LUA_COMPAT_MATHLIB #39

Closed ToxicFrog closed 4 years ago

ToxicFrog commented 4 years ago

This requires us to write a pure-lua replacement for math.frexp() that works for everything, including numbers very close to 0 or infinity.

deepakjois commented 4 years ago

Here is a link which contains a Lua 5.3 polyfill for the frexp function: https://github.com/excessive/cpml/blob/master/modules/utils.lua#L18

In my code, I had

local frexp = math.frexp or function(x)
    if x == 0 then return 0, 0 end
    local e = floor(log(abs(x)) / log2 + 1)
    return x / 2 ^ e, e
end

which is identical to the code above, except that I was missing a couple of lines above:

local log2 = log(2)

So, maybe that was the actual issue, i.e. that log2 was undefined and thus the polyfill in my code was not working as it should? If you can test that hypothesis, maybe you can put the polyfill back with the missing two lines.

ToxicFrog commented 4 years ago

Yeah, that polyfill does not work as is, even once the missing reference to log2 is corrected; it's fine for most numbers, but for numbers very close to infinity the intermediate term 2^e produces inf.

e4c0a67046b82fbb2792c94ae61874b32626c487 adds a version that handles the near-infinity case correctly and also ensures that the values produced are in the correct range to match the builtin.