2012-03-06 165 views
42

對於Java中的某些哈希函數,將該值視爲無符號整數(例如,用於與其他實現進行比較)會很好,但是Java僅支持簽名類型。我們可以將簽署int轉換爲「無符號」 long這樣:將有符號整數轉換爲無符號長整型的最佳方法?

public static final int BITS_PER_BYTE = 8; 
public static long getUnsignedInt(int x) { 
    ByteBuffer buf = ByteBuffer.allocate(Long.SIZE/BITS_PER_BYTE); 
    buf.putInt(Integer.SIZE/BITS_PER_BYTE, x); 
    return buf.getLong(0); 
} 
getUnsignedInt(-1); // => 4294967295 

然而,這種解決方案似乎是矯枉過正我們真正做的事情。有沒有更高效的方法來實現同樣的目標?

回答

78

像這樣的東西?

int x = -1; 
long y = x & 0x00000000ffffffffL; 

或者我錯過了什麼?

public static long getUnsignedInt(int x) { 
    return x & 0x00000000ffffffffL; 
} 
+0

+1。不,是我失去了一些東西 - 我把自己與擴大轉換混爲一談,忽略了簡單的方法=) – maerics 2012-03-06 06:04:09

+0

呃,它發生了。特別是在C++中,有一些方法可以完成所有工作。 – Mysticial 2012-03-06 06:06:34

+4

'x&0xFFFFFFFFL'也可以嗎? – Paranaix 2012-11-29 16:33:20

2

其他解決方案。

public static long getUnsignedInt(int x) { 
    if(x > 0) return x; 
    long res = (long)(Math.pow(2, 32)) + x; 
    return res; 
} 
+4

Math.pow非常昂貴並且每次都會計算。比較而言'1l << 32'很快,只能由編譯器計算。 (並且不需要投入很長時間 – 2012-03-06 08:23:06

+0

您可以給我一些關於這些轉換如何工作的鏈接或描述,因爲int不能理解它 – 2012-09-28 09:45:10

+1

因爲int是32位並且使用二進制補碼來表示。可以在wikipedia(http://en.wikipedia.org/wiki/Two's_complement)中查看二進制補碼以獲得更多詳細信息 – lmatt 2012-11-14 09:15:53

7

但是,您可以在你不需要做這個大多數情況下使用的功能像

public static long getUnsignedInt(int x) { 
    return x & (-1L >>> 32); 
} 

。您可以改用替代方法。例如

public static boolean unsignedEquals(int a, int b) { 
    return a == b; 
} 

有關使用無符號值的變通方法的更多示例。 Unsigned utility class

+0

您的getUnsignedInt函數不起作用我在程序中犯了一個嚴重的錯誤,因爲我沒有測試它:(。(( – user2707175 2014-07-08 20:08:45

+0

@ user2707175把'>>>'改成'>>'並且它應該可以工作 – 2016-08-31 21:24:25

+0

getUnsignedInt似乎按原樣工作。>>>是正確的。>>導致符號擴展和 - 1L右移符號擴展的任何數值總是會導致一個全1的值 – AgentME 2017-10-18 17:48:03

-3
long abs(int num){ 
    return num < 0 ? num * -1 : num; 
} 
-2

只是我的2美分,在這裏,但我認爲這是一個很好的做法是使用:的

public static long getUnsignedInt(int x) { return x & (~0L); // ~ has precedence over & so no real need for brackets }

代替:

返回X & 0xFFFFFFFFL;

在這種情況下,你不擔心有多少'F的面具。它應該始終工作!

+1

這是完全錯誤的,int被提升爲一個long,然後你用一個64位的字符串掩蓋它,它不做任何事情。以下打印-1代替o f 4294967295: int i = -1; long j = i&(〜0L); System.out.println(j); – PBJ 2015-04-23 20:02:41

+0

是的,這是我的不好,我弄糊塗0xFFFFFFFFL與〜0L這顯然不是這種情況 – okoopat 2015-06-17 12:10:05

相關問題