以64位长的形式包装4个整数 - java按位

时间:2010-02-25 14:37:39

标签: java bit-manipulation long-integer

好吧,所以我有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数据类型有关,但我还没有找到任何东西,这支持了这个理论。

1 个答案:

答案 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);