はなぜJavaは-2147483648を返すのですか?ビットシフト演算が期待される結果を返さない私は をシフトするビット際
期待される結果が
..ウルフラムアルファと私の電卓でテスト9 223 372 036 854 775 808であり、私がテストした:
System.out.print((ロング)(1 < <(63)));
はなぜJavaは-2147483648を返すのですか?ビットシフト演算が期待される結果を返さない私は をシフトするビット際
期待される結果が
..ウルフラムアルファと私の電卓でテスト9 223 372 036 854 775 808であり、私がテストした:
System.out.print((ロング)(1 < <(63)));
あなたがlongにキャストあなたはまず(1 << 63)
、およびを取るライン
System.out.print((long)(1 << (63)));
について注意すべき重要な事があります。その結果、実際には整数で左シフトしているので、長いキャストは効果がありません。そのため、63ビット左にシフトすると、minよりもむしろ最小の整数が得られます。
しかし、重要な点がもう一つあります。 Java longは常に署名されているので、さらに行しても
System.out.print(1L << 63);
となります。 2の補数の下では、左端のビットが1であるときはいつでも、その数は負である。
その数が最大の長よりも大きい、とlong
最大のプリミティブ型であるため、あなたは実際に、Javaのプリミティブ型で数2 = 9223372036854775808を表現することはできません。あなたはBigIntegerとしてこの番号を表すことができます。あなたも、あなたがinteger overflow [倍]を持っているコード
BigInteger.ONE.shiftLeft(63)
63によって左シフトを経由して、それを生成することができます。
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))
を行う
long
に[
-2147483648
ある]
1 << (63)
の結果をキャストしている - そしてそれは、その値を変更しません。
溢れていることを指摘して説明してくれてありがとう!私はOpenJDKのBitSet実装で見つかったこのコードの説明を探しています:[long firstWordMask = WORD_MASK << fromIndex;長いlastWordMask = WORD_MASK >>> -InIndex; ]この場合、WORD_MASKは長いですが。 – ruizpauker
ありがとうございました。実際には今実際にはっきりしています –
+1また、実用的なソリューションも含まれています。 p.s.私はあなたが2^63をより読みやすいものに編集する自由を取ったことを気にしないことを願っています。 – amit
@amitいいえ、私はまったく気にしません。ありがとう! –