lua-users home
lua-l archive

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


I have such functions in my Lunary serialization library, which handle
nan (just one), +/- inf, denormalized numbers, single/double precision
and little/big endianness. For example for doubles:

https://bitbucket.org/doub/lunary/src/47f3daa726aacf854b21d709c297711e637b859d/5.2/serial.lua#cl-1297

Feel free to use (without credit, it's based on snippets found here and there).

2015-03-11 11:22 GMT+00:00 Jakub Sztandera <k.sztandera@hotmail.com>:
> 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