2011-02-28 49 views
7

我有一種感覺,這是一個相當微不足道的問題,但我很難過。在我的應用程序中,我用一對int鍵在查找表中鍵入事物。我認爲將兩個整數連接成一個長整型並將單長整型作爲一個鍵會更容易。從C背景的,我希望像這樣的工作:在Java中向上轉換或移位時抑制符號擴展

int a, b; 
long l = (long)a << 32 | b; 

我試圖在Java中複製這種已經我感到沮喪。特別是,因爲沒有無符號的整型,所以我似乎無法避免b的自動符號擴展(a是左移的,所以它是不相關的)。我嘗試過使用b & 0x00000000FFFFFFFF,但它出乎意料地沒有效果。我也嘗試了相當醜陋的(long)b <<32>> 32,但它似乎被編譯器優化了。

我曾希望嚴格使用位操作來處理原語,但我開始懷疑是否需要使用某種緩衝對象來實現這一點。

+3

'(長)b << 32 >> 32'沒有優化出來。主要問題是>> sra和>>>是srl,這是你想要的:'(long)b << 32 > >> 32' – ide 2011-02-28 21:30:26

+0

表達式'b&0x00000000FFFFFFFF'只是必須的,但爲什麼你要混淆它由那些零? – maaartinus 2011-02-28 21:39:20

+0

@maaartinus:我對Java不熟悉,不知道它在內部存儲了那個十六進制文字。我知道在C十六進制文字是無符號的,但我擔心0xFFFFFFFF將被簽名擴展。事後看來,我只需要一個領先的零來滿足這個問題。儘管如此,表達沒有任何效果。 – 2011-02-28 21:42:54

回答

16

我總是用我的實用工具類

public static long compose(int hi, int lo) { 
    return (((long) hi << 32) + unsigned(lo)); 
} 
public static long unsigned(int x) { 
    return x & 0xFFFFFFFFL; 
} 

public static int high(long x) { 
    return (int) (x>>32); 
} 
public static int low(long x) { 
    return (int) x; 
} 

對於任何int x, y(負或不)

high(compose(x, y)) == x 
low(compose(x, y)) == y 

持有和任何long z

compose(high(z), low(z)) == z 

也是。

+0

如果可以的話,你會不止一次地提醒你,簽名擴展是駕駛遇見的堅果。 – Michael 2011-09-13 12:16:52

+0

不應該'高'使用'>>>'而不是'>>'? – 2017-06-18 14:58:04

+0

@JamesKo移位後的值僅在其高32位不同,即在由演員剪掉的那些值中。您可能希望使用無符號移位來證明您沒有處理簽名,但我選擇使用簽名移位來證明它無關緊要。 ;) – maaartinus 2017-06-18 15:01:59

1

我會不時地這樣做 - 我在一個長整數中存儲兩個整數,用於我的X Y座標。因爲我知道我的範圍絕不會超過十億,我做了以下內容:

private Long keyFor(int x, int y) { 
    int kx = x + 1000000000; 
    int ky = y + 1000000000; 
    return (long)kx | (long)ky << 32; 
} 

private Long keyFor(int[] c) { 
    return keyFor(c[0],c[1]); 
} 

private int[] coordsFor(long k) { 
    int x = (int)(k & 0xFFFFFFFF) - 1000000000; 
    int y = (int)((k >>> 32) & 0xFFFFFFFF) - 1000000000; 
    return new int[] { x,y }; 
} 
+0

我已將課程上傳到Pastebin:http://pastebin.com/89W4SwCV – corsiKa 2011-02-28 21:32:30

+0

這不是一個通用的解決方案,它使得構圖難以破譯。以正常方式編寫數字的速度更快,並且允許直接在十六進制輸出中查看組件。 – maaartinus 2011-02-28 21:42:46

+0

「以正常方式編寫數字」不起作用 - 如果確實如此,我不會採取這種方式。這是OP運行的確切問題。並不是所有難以遵循的。我當然並不認爲這是一個失望的標準,因爲這是一個潛在的解決方案,即使你覺得它比所需的更混亂。 – corsiKa 2011-02-28 22:14:53