2010-02-25 73 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