从两个单位获取数字

发布于 2024-10-26 03:07:27 字数 395 浏览 6 评论 0原文

我正在 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 会很好)。

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).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清眉祭 2024-11-02 03:07:27

是的,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);
}

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);
}
泛泛之交 2024-11-02 03:07:27

我找到了自己的解决方案(仅适用于正数)

(Number(msb) * Math.pow(2, 32)) + Number(lsb)

或硬编码 2^32

(Number(msb) ) * 4294967296) + 数字(lsb)

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)

﹎☆浅夏丿初晴 2024-11-02 03:07:27

readDouble()
更新:

var ba:ByteArray = new ByteArray();
ba.writeUnsignedInt(uint1);
ba.writeUnsignedInt(uint2);
ba.position = 0;
result = ba.readDouble();

readDouble()
upd:

var ba:ByteArray = new ByteArray();
ba.writeUnsignedInt(uint1);
ba.writeUnsignedInt(uint2);
ba.position = 0;
result = ba.readDouble();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文