将 4 个整数包装在 64 位长中 - java 按位

发布于 2024-08-23 07:17:56 字数 1431 浏览 4 评论 0原文

好吧,我有 4 个整数想要用 long 包装起来。 这 4 个整数都包含 3 个值,位于前 2 个字节中:

 +--------+--------+
 |xxpppppp|hdcsrrrr|
 +--------+--------+

{pppppp} 表示一个值,{hdcs} 表示第二个值,{rrrr} 表示最后一个值。

我想将 4 个这样的整数打包成一个 long。我尝试了以下操作:

ordinal = (c1.ordinal() << (14*3) | c2.ordinal() << (14*2) | c3.ordinal() << 14 | c4.ordinal());

其中 c1.ordinal()...c4.ordinal() 是要换行的整数。

如果我运行测试,这似乎不起作用。假设我想查找长整型 c4.ordinal() 中最后一个整数的值,其中 {pppppp} = 41、{hdcs} = 8 和 {rrrr} = 14,我得到以下结果:

System.out.println(c4.ordinal() & 0xf); //Prints 14
System.out.println(hand.ordinal() & 0xf); // Prints 14 - correct

System.out.println(c4.ordinal() >> 4 & 0xf); // Prints 8
System.out.println(hand.ordinal() >> 4 & 0xf); // Prints 8 - correct

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 61 - NOT correct!

现在,以下结果对我来说很奇怪。如果我删除前两个整数,只包装最后两个整数,如下所示:

ordinal = (c3.ordinal() << 14 | c4.ordinal());

并运行相同的测试,我会得到正确的结果:

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 41 - correct!

我不知道出了什么问题。如果删除前两个整数,我会得到正确的答案,这对我来说没有任何意义。我开始认为这可能与长数据类型有关,但我还没有找到任何支持这一理论的东西。

Alright, so I have 4 integers I want to wrap in a long.
The 4 integers all contains 3 values, positioned in the first 2 bytes:

 +--------+--------+
 |xxpppppp|hdcsrrrr|
 +--------+--------+

{pppppp} represents one value, {hdcs} represents the second and {rrrr} the last.

I want to pack 4 of these integers, in a long. I've tried the following:

ordinal = (c1.ordinal() << (14*3) | c2.ordinal() << (14*2) | c3.ordinal() << 14 | c4.ordinal());

where c1.ordinal()...c4.ordinal() is the integers to wrap.

This does not seem to work if I run a test. Lets say I want to look up the values of the last integer in the long, c4.ordinal(), where {pppppp} = 41, {hdcs} = 8 and {rrrr} = 14, I get the following results:

System.out.println(c4.ordinal() & 0xf); //Prints 14
System.out.println(hand.ordinal() & 0xf); // Prints 14 - correct

System.out.println(c4.ordinal() >> 4 & 0xf); // Prints 8
System.out.println(hand.ordinal() >> 4 & 0xf); // Prints 8 - correct

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 61 - NOT correct!

Now, the following is weird to me. If I remove the first two integers, and only wrap the last two, like this:

ordinal = (c3.ordinal() << 14 | c4.ordinal());

And run the same test, I get the correct result:

System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 41 - correct!

I have no idea whats wrong. And it does not make any sense to me, that I get the correct answer if I remove the first two integers. I'm starting to thing this might have to do with the long datatype, but I've not found anything yet, that supports this theory.

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

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

发布评论

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

评论(1

白馒头 2024-08-30 07:17:56

即使您将结果分配给 long,所有操作都是使用 int 值执行的,因此高位会丢失。通过显式将值扩展为 long 来强制“提升”为 long

long ordinal = (long) c1.ordinal() << (14*3) | 
               (long) c2.ordinal() << (14*2) | 
               (long) c3.ordinal() <<    14  | 
               (long) c4.ordinal();

此外,除非您确信每个值的前两位为零,否则可能会遇到其他问题。为了安全起见,您可能希望屏蔽这些内容:

long ordinal = (c1.ordinal() & 0x3FFFL) << (14*3) | 
               (c2.ordinal() & 0x3FFFL) << (14*2) | 
               (c3.ordinal() & 0x3FFFL) <<    14  | 
               (c4.ordinal() & 0x3FFFL);

Even though you are assigning the result to a long, all of the operations are performed with int values, and so the high-order bits are lost. Force "promotion" to a long by explicitly widening the values to a long.

long ordinal = (long) c1.ordinal() << (14*3) | 
               (long) c2.ordinal() << (14*2) | 
               (long) c3.ordinal() <<    14  | 
               (long) c4.ordinal();

Also, unless you are positive that the top two bits of each value are zero, you could run into other problems. You may wish to mask these off for safety's sake:

long ordinal = (c1.ordinal() & 0x3FFFL) << (14*3) | 
               (c2.ordinal() & 0x3FFFL) << (14*2) | 
               (c3.ordinal() & 0x3FFFL) <<    14  | 
               (c4.ordinal() & 0x3FFFL);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文