lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 11 March 2015 at 07:22, Jakub Sztandera <k.sztandera@hotmail.com> wrote:
> Hello,
> couldn't find anything like that in internet so I wrote my own.
> It converts Lua's double from and to byte array.
> It does not handle well special values, like INF, NaN (they get mixed up)
> but it handles all normalized  numbers (as far as I know).
> Used bit order is little-endian but modifying it to big-endian shouldn't be
> hard (but little-endian is pretty much standard for floating point).
>
> I post this here as I am sure that someone will be some day seeking such
> tool and archives of this list are the best place I could think of to
> publish this code.
>
> Code is on MIT licence, so do whatever you want.
>
> function readDouble(bytes)
>   local sign = 1
>   local mantissa = bytes[2] % 2^4
>   for i = 3, 8 do
>     mantissa = mantissa * 256 + bytes[i]
>   end
>   if bytes[1] > 127 then sign = -1 end
>   local exponent = (bytes[1] % 128) * 2^4 + math.floor(bytes[2] / 2^4)
>
>   if exponent == 0 then
>     return 0
>   end
>   mantissa = (math.ldexp(mantissa, -52) + 1) * sign
>   return math.ldexp(mantissa, exponent - 1023)
> end
>
> function writeDouble(num)
>   local bytes = {0,0,0,0, 0,0,0,0}
>   if num == 0 then
>     return bytes
>   end
>   local anum = math.abs(num)
>
>   local mantissa, exponent = math.frexp(anum)
>   exponent = exponent - 1
>   mantissa = mantissa * 2 - 1
>   local sign = num ~= anum and 128 or 0
>   exponent = exponent + 1023
>
>   bytes[1] = sign + math.floor(exponent / 2^4)
>   mantissa = mantissa * 2^4
>   local currentmantissa = math.floor(mantissa)
>   mantissa = mantissa - currentmantissa
>   bytes[2] = (exponent % 2^4) * 2^4 + currentmantissa
>   for i= 3, 8 do
>     mantissa = mantissa * 2^8
>     currentmantissa = math.floor(mantissa)
>     mantissa = mantissa - currentmantissa
>     bytes[i] = currentmantissa
>   end
>   return bytes
> end
>
> Available also on https://gist.github.com/Kubuxu/e5e04c028d8aaeab4be8
> where in case of found errors updates will be released.
>
> ________________________________
>
> Best Regards
> Jakub (Kubuxu) Sztandera

I wrote one where I cheated:
https://github.com/daurnimator/mmdblua/blob/f0644b7478ec91fd8a7d85a9f0f259f444ba20cd/IEEE-754.lua

However, in Lua 5.3 you don't need to do this (and infact math.ldexp
is removed): we have string.(un)pack.
Use the 'd' specifier for doubles:
http://www.lua.org/manual/5.3/manual.html#6.4.2
This has been backported as part of lua-compat-5.3:
https://github.com/keplerproject/lua-compat-5.3
A similar api is available via Robertos' struct library:
http://www.inf.puc-rio.br/~roberto/struct/
See also, vstruct: https://github.com/ToxicFrog/vstruct