Problem with Lua struct.pack() and 64bit longs

319 views
Skip to first unread message

Ondřej Nešpor

unread,
Aug 14, 2014, 3:32:39 AM8/14/14
to redi...@googlegroups.com
Hi everybody,

today, I've encountered a strange thing in Redis and Lua. I am using Redis 2.8.13 on Linux and I need to process some data in Redis (Lua) and put the result (a couple of longs) into a list so that a bunch of (Java) applications can process it later asynchronously. I wanted to use the struct.pack() function to create binary data so that we could use ByteBuffer to read those longs in Java.

However for some reason the struct.pack() function screws my longs :)

eval 'return {struct.unpack("l", struct.pack("l", "74134242078883838"))}' 0
1) (integer) 74134242078883840
2) (integer) 9

eval 'return {struct.unpack("l", struct.pack("l", "74126054835224577"))}' 0
1) (integer) 74126054835224576
2) (integer) 9

And from my experience the problem is with the pack() part. When I read the binary data in Java I get the same wrong numbers.

It doesn't really matter if I tell it to be big or little endian, use "l" or "i8" or pass the number as number or string. It seems that for some reason it rounds the number to 2^16 and it seems that it does it for numbers bigger than cca 2^54 - 1.

Is it a bug in the struct library or does it by "long" mean something else than I do (64bit signed integer)? :)


Thanks!


Andrew

Javier Guerra Giraldez

unread,
Aug 14, 2014, 12:45:45 PM8/14/14
to redi...@googlegroups.com
On Thu, Aug 14, 2014 at 2:32 AM, Ondřej Nešpor <ondrej...@gmail.com> wrote:
> Is it a bug in the struct library or does it by "long" mean something else
> than I do (64bit signed integer)? :)


It's a limitation of Lua, the only number type it handles is IEEE
double (64-bit float). the struct library does pack 'long' fields as
64-bit integers, but when passed as a Lua value they're casted through
a double.

as you have found out, a double has integer precision only up to 2^53.

--
Javier
Reply all
Reply to author
Forward
0 new messages