好吧,所以我有4个整数,我想用很长的时间换行。 4个整数都包含3个值,位于前2个字节中:
+--------+--------+
|xxpppppp|hdcsrrrr|
+--------+--------+
{pppppp}代表一个值,{hdcs}代表第二个值,{rrrr}代表最后一个值。
我想长时间打包4个这样的整数。我尝试了以下内容:
ordinal = (c1.ordinal() << (14*3) | c2.ordinal() << (14*2) | c3.ordinal() << 14 | c4.ordinal());
其中c1.ordinal()... c4.ordinal()是要包装的整数。
如果我运行测试,这似乎不起作用。假设我想查找long 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!
我不知道什么是错的。对我来说没有任何意义,如果我删除前两个整数,我得到正确的答案。我开始讨论这可能与long数据类型有关,但我还没有找到任何东西,这支持了这个理论。
答案 0 :(得分:6)
即使您将结果分配给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);