Fre*_*old 0 java bit-manipulation long-integer
好吧,所以我有4个整数,我想包裹很长一段时间.4个整数都包含3个值,位于前2个字节中:
+--------+--------+
|xxpppppp|hdcsrrrr|
+--------+--------+
Run Code Online (Sandbox Code Playgroud)
{pppppp}代表一个值,{hdcs}代表第二个值,{rrrr}代表最后一个值.
我想在很长一段时间内打包4个这样的整数.我尝试过以下方法:
ordinal = (c1.ordinal() << (14*3) | c2.ordinal() << (14*2) | c3.ordinal() << 14 | c4.ordinal());
Run Code Online (Sandbox Code Playgroud)
其中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!
Run Code Online (Sandbox Code Playgroud)
现在,以下内容对我来说很奇怪.如果我删除前两个整数,只包装最后两个,如下所示:
ordinal = (c3.ordinal() << 14 | c4.ordinal());
Run Code Online (Sandbox Code Playgroud)
并运行相同的测试,我得到正确的结果:
System.out.println(c4.ordinal() >> 8 & 0x3f); // Prints 41
System.out.println(hand.ordinal() >> 8 & 0x3f); // Prints 41 - correct!
Run Code Online (Sandbox Code Playgroud)
我不知道什么是错的.对我来说没有任何意义,如果我删除前两个整数,我得到正确的答案.我开始这可能与long数据类型有关,但我还没有找到任何东西,这支持这个理论.
即使您将结果分配给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();
Run Code Online (Sandbox Code Playgroud)
此外,除非你肯定每个值的前两位是零,否则你可能遇到其他问题.为安全起见,您可能希望屏蔽它们:
long ordinal = (c1.ordinal() & 0x3FFFL) << (14*3) |
(c2.ordinal() & 0x3FFFL) << (14*2) |
(c3.ordinal() & 0x3FFFL) << 14 |
(c4.ordinal() & 0x3FFFL);
Run Code Online (Sandbox Code Playgroud)