2014-04-07 84 views
5

Java 8被廣泛報道具有對無符號整數的庫支持。然而,似乎沒有文章解釋如何使用它以及可能有多少。Java8無符號算術

一些像Integer.CompareUnsigned這樣的函數很容易找到並且似乎按照人們的期望來做。然而,我甚至沒有寫出一個簡單的循環,它在無符號long的範圍內循環遍歷兩個冪。

int i = 0; 
for(long l=1; (Long.compareUnsigned(l, Long.MAX_VALUE*2) < 0) && i<100; l+=l) { 
    System.out.println(l); 
    i++; 
} 

產生輸出

1 
2 
4 
8 
... 
1152921504606846976 
2305843009213693952 
4611686018427387904 
-9223372036854775808 
0 
0 
0 
... 
0 

我缺少的東西或者外部庫仍然需要這種簡單的任務?

回答

6

如果你指的是

(Long.compareUnsigned(l, Long.MAX_VALUE*2) < 0) 

l達到

-9223372036854775808 

簽名是

9223372036854775808 

Long.MAX_VALUE*2 

18446744073709551614 

所以l是無符號的世界比Long.MAX_VALUE*2小。

假設你問的是0的

0 
0 
0 
... 
0 

問題(如果你這樣認爲)是,對於long(其它數值元),第一位爲符號位。

所以

10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

-9223372036854775808 

當你

-9223372036854775808 + -9223372036854775808 

你溢(溢出?)因爲

10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 
+ 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 

這是0。以後的循環迭代,0 + 0保持0

+0

這很有道理。那麼終止這個循環的正確方法是什麼? –

+0

(Long.compareUnsigned(1,46116860184273879041 * 4)!= 0)似乎有效,但有沒有更明顯的方法? –

+0

@Jannis你只想找到最後一個值'18446744073709551614'? –

4

這裏唯一的問題是,你打印l作爲簽署整數。您可以使用Integer.toUnsignedString得到的結果你期待:

int i = 0; 
byte[] tmp = new byte[9]; 
for(int l=1; (Long.compareUnsigned(l, Long.MAX_VALUE*2) < 0) && i<100; l+=l) { 
    System.out.println(Integer.toUsignedString(l)); // <== MODIFIED THIS LINE 
    i++; 
} 
+0

因爲'l'永遠不會比Long長。MAX_VALUE * 2,我懷疑循環永遠不會終止。 –

+1

@JoachimIsaksson - 這裏還有一個&& i <100'條款。但是,我認爲OP會明白'int'和'long'並不是一回事。如果沒有,那麼Sotirios的回答澄清了這一點。 – DaoWen

+0

修正了最後一個正確數字的輸出,但之後我仍然只得到0 –