Reputation: 44104
I'm reading a signed 64 bit integer (Java long
) from the network in Flash+ActionScript3, and storing it as two uint
's (first and last 32 bits).
var l:LongNumber = new LongNumber();
l.msb = socket.readUnsignedInt();
l.lsb = socket.readUnsignedInt();
How can I convert it into the actual number as a Number
?
I'm aware Number
can contain only 53 bit integers, not 64, but it's enough (though being able to throw an Error
when converting larger numbers would be nice).
Upvotes: 2
Views: 552
Reputation: 1937
Yes, readDouble() is useless here, it will interpret your 64 bit integer as an IEEE 754 formatted double-precision float (sign bit + 11 exponent bits + 52 fraction bits) and that will get you a garbage result.
(Number(msb) * Math.pow(2, 32)) + Number(lsb) isn't a complete solution if you need to support negative numbers. This code only gets the correct result if your number is zero or a positive number no greater than 2^63-1 (such that the sign bit is not set). If the sign bit is set, your code will effectively be interpreting the 64 bits as an unsigned integer, which is not what Java is sending you. If you're using your solution and wondering why you're always getting a positive result, this is why.
There is probably some really cool bit trick to support negative and positive numbers in one line of code, but because I can't work that out right now, I'll tell you the straight-forward way I see the solution in my mind:
I would use msb & 0x80000000 to read sign bit. If it's not set, use your formula above. If it is set, convert your number from 2's complement format to unsigned format first:
msb = (msb ^ 0xFFFFFFFF);
lsb = (lsb ^ 0xFFFFFFFF) + 1;
Then apply your forumla to the msb and lsb and (because the sign bit was set) multiply the resulting Number by -1.
if (msb & 0x80000000)
{
msb ^= 0xFFFFFFFF;
lsb ^= 0xFFFFFFFF;
result = -(Number(msb)*4294967296 + Number(lsb) + 1);
}
else
{
result = Number(msb)*4294967296 + Number(lsb);
}
Upvotes: 1
Reputation: 44104
I found my own solution (only for positive numbers)
(Number(msb) * Math.pow(2, 32)) + Number(lsb)
or hardcoding 2^32
(Number(msb) * 4294967296) + Number(lsb)
Upvotes: 1
Reputation: 4434
readDouble()
upd:
var ba:ByteArray = new ByteArray();
ba.writeUnsignedInt(uint1);
ba.writeUnsignedInt(uint2);
ba.position = 0;
result = ba.readDouble();
Upvotes: 0