我正在从Flash + ActionScript3中的网络读取一个带符号的64位整数(Java long
),并将其存储为两个uint
(第一个和最后一个32位)。
var l:LongNumber = new LongNumber();
l.msb = socket.readUnsignedInt();
l.lsb = socket.readUnsignedInt();
如何将其转换为Number
的实际数字?
我知道Number
只能包含53位整数,而不是64位,但这已经足够了(虽然在转换较大数字时能够抛出Error
会很好。)
答案 0 :(得分:1)
我找到了自己的解决方案(仅适用于正数)
(Number(msb) * Math.pow(2, 32)) + Number(lsb)
或硬编码2 ^ 32
(Number(msb) * 4294967296) + Number(lsb)
答案 1 :(得分:1)
是的, readDouble()在这里没用,它会将你的64位整数解释为IEEE 754格式的双精度浮点数(符号位+ 11指数位+ 52小数位),这将是给你一个垃圾结果。
(Number(msb)* Math.pow(2,32))+ Number(lsb)如果您需要支持负数,则不是完整的解决方案。如果您的数字为零或正数不大于2 ^ 63-1(这样符号位未设置),此代码仅获得正确的结果。如果设置了符号位,则代码将有效地将64位解释为无符号整数,这不是Java发送给您的。如果你正在使用你的解决方案,并想知道为什么你总是得到积极的结果,这就是原因。
在一行代码中支持负数和正数可能有一些非常酷的技巧,但由于我现在无法解决这个问题,我会告诉你我直截了当地看到解决方案的方法我的想法:
我会使用 msb& 0x80000000 读取符号位。如果未设置,请使用上面的公式。如果已设置,请先将数字从2的补码格式转换为无符号格式:
msb =(msb ^ 0xFFFFFFFF);
lsb =(lsb ^ 0xFFFFFFFF)+ 1;
然后将您的forumla应用于msb和lsb并且(因为符号位已设置)将得到的数字乘以-1。
if (msb & 0x80000000)
{
msb ^= 0xFFFFFFFF;
lsb ^= 0xFFFFFFFF;
result = -(Number(msb)*4294967296 + Number(lsb) + 1);
}
else
{
result = Number(msb)*4294967296 + Number(lsb);
}
答案 2 :(得分:0)
readDouble()
的 UPD:强>
var ba:ByteArray = new ByteArray();
ba.writeUnsignedInt(uint1);
ba.writeUnsignedInt(uint2);
ba.position = 0;
result = ba.readDouble();