0

好的,所以我有 4 个整数我想用 long 包装。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!

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

4

1 回答 1

6

即使您将结果分配给 a long,所有操作都是使用int值执行的,因此高位会丢失。long通过将值显式扩大到 a 来强制“提升”到a 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);
于 2010-02-25T15:00:09.883 回答