2010-02-25 41 views
0

好吧,所以我有4个整数我想长期包装。 的4个整数所有包含3个值,定位在第一2个字节:包装4位整数在64位长 - java按位

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

{PPPPPP}表示一个值,{HDCS}表示第二和{RRRR}最后一个。

我要收拾这些整数4,在很长的。我试过以下内容:

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! 

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

+0

@Frederik:你为什么要以14的倍数上移,并为4的倍数下移? – Welbog 2010-02-25 15:02:45

+0

由于16位值的最后两位始终为0,所以它们无关紧要。 3个值中的2个是4位长,所以我每次移位4。 (最后一个是6位长,所以我需要使用另一个掩码来表示这个值)。 – 2010-02-25 15:15:12

回答

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); 
+0

你太棒了!谢谢:) – 2010-02-25 15:05:59

+0

这是常识吗? Sun并没有真正说明我遇到过的任何地方...... – 2010-02-25 15:07:08

+0

非常多 - 而且它不是特定于Java的。运营商正与一个类型时,并分配到不同的类型,通常需要任何计算... 这使得更多的意义,因为一个简单的例子,这可能是java,C或C++之前源类型转换: INT X1 = 1; int x2 = 2; float y = x1/x2; ÿ== 0 浮子Z =((浮点)X1)/((浮动)×2); ž== 0.5F (ACK,评论没有换行符) – CuriousPanda 2010-02-25 15:11:18