int の最大値が 2 31 -1であるにもかかわらず、Java HashMap の最大容量が 1<<31 ではなく 1<<30 であるのはなぜですか? 最大容量は次のように初期化されます。static final int MAXIMUM_CAPACITY = 1 << 30;
4 に答える
Java は符号付き整数を使用します。これは、最初のビットが数値の符号 (正/負) を格納するために使用されることを意味します。
4 バイト整数には 32 ビットがあり、数値部分は符号ビットのために 31 ビットしかスパンしない場合があります。これにより、数値の範囲が2^31 - 1 (0 が含まれるため) から- (2^31)に制限されます。
より大きな整数型を使用しなくても、ハッシュ マップが 2^30 から 2^31-1 の間の項目の数量を処理することは可能ですが、言語の整数型の上限近くでも正しく動作するコードを書くことは困難です。さらに、整数をオーバーフロー時に「ラップ」する抽象的な代数リングとして扱う言語では、数値的に正しい結果を生成するか、それができない場合に例外をスローする数値としてではなく、オーバーフローによって無効な操作が検出されないケースはありません。
2^30 または 2^29 の上限を指定し、それよりも大きくないものに対して正しい動作を保証することは、多くの場合、2^31-1 まで正しい動作を保証しようとするよりもはるかに簡単です。範囲の最後のビットをすべて絞り出す特別な理由がない限り、通常はより単純なアプローチを使用することをお勧めします。
デフォルトでは、int
データ型は32 ビットの符号付き 2 の補数整数で、最小値は-2^31
、最大値は(2^31)-1
–2,147,483,648 ~ 2,147,483,647 です。
最初のビットは符号ビット用に予約されています。数値が負の場合は 1、正の場合は 0 です。
1 << 30
は1,073,741,824
に等しく、2 の補数の 2 進整数は 01000000-00000000-00000000-00000000 です。
1 << 31
は-2,147,483,648です。
2 の補数の 2 進整数は 10000000-00000000-00000000-00000000 です。
hash-map が展開できる最大サイズは 1,073,741,824 = 2^30 です。
符号なしを考えていますが、符号付きの上限範囲は (2^31)-1 です