[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Double to byte array and byte array to double conversion in plain Lua.
- From: Daurnimator <quae@...>
- Date: Wed, 11 Mar 2015 12:52:27 -0400
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