2012-03-26 75 views

回答

27

有需要注意行

System.out.print((long)(1 << (63))); 

一件重要的事你先(1 << 63),並然後你投來長。結果,你實際上是左移整數,所以長投並沒有任何效果。這就是爲什麼將63位左移給出最小整數而不是最小長度的原因。

但還有另一個更重要的觀點。 Java longs總是有符號的,所以即使是行

System.out.print(1L << 63); 

會給一個負數。在二進制補碼下,只要最左邊的位是1,該數字就是負數。

實際上,你不能代表數字2 在Java原始類型= 9223372036854775808,因爲這個數字比最大長做大,long是最大的基本類型。不過,您可以將此號碼錶示爲BigInteger。甚至可以通過由63與代碼

BigInteger.ONE.shiftLeft(63) 
+0

噢謝謝你,現在真的很清楚 – 2012-03-26 22:53:33

+0

+1爲一個很好的答案,其中還包括實用的解決方案。附:我希望你不介意我冒昧地把2^63編輯成更具可讀性的東西。 – amit 2012-03-26 23:02:37

+0

@amit不,我根本不介意。謝謝! – 2012-03-27 01:28:52

6

您具有integer overflow [兩次]左移生成它。

1 << 32 == 1 
1 << 31 == -2147483648 [ becuase this is the binary representation in 2's complement for -2147483648] 
1 << 63 == 1 << (32 + 31) == (1 << 32) << 31 == 1 << 31 == -2147483648 

當你做(long)(1 << (63))你只鑄造1 << (63)結果[這是-2147483648]對long - 它不會改變它的值。

+0

感謝您指出並描述了溢出!我一直在尋找OpenJDK的BitSet實現上的代碼的解釋:[long firstWordMask = WORD_MASK << fromIndex; long lastWordMask = WORD_MASK >>> -toIndex; ],即使在這種情況下WORD_MASK很長。 – ruizpauker 2016-09-10 08:22:52