では、右シフト演算で負の数がどう扱われるかを図で丁寧に解説します。Javaの >> と >>> の違いも含めて、初心者向けに段階的に説明します。
1. 符号付き右シフト >>(Arithmetic Shift Right)
- 目的:ビットを右にずらす
- 特徴:左端(最上位ビット)は 符号ビットを維持
- 正の数なら左端に0を入れる
- 負の数なら左端に1を入れる
- 結果:負の数は負のままシフトされる
例:-8 >> 2(8ビットイメージ)
-8を2の補数で表す
-8 = 1111 1000 (8ビット)
- 右に2ビットシフト(符号ビットを維持)
1111 1000 >> 2 → 1111 1110
- 結果を10進数で見る
1111 1110 = -2
✅ ポイント:負の数でも符号を保持するので、-8 / 4 = -2 と同じ結果になります。
2. 符号なし右シフト >>>(Logical Shift Right)
- 目的:ビットを右にずらす
- 特徴:左端は 常に0 で埋める
- 結果:負の数も正の大きな値に変わることがある
例:-8 >>> 2(8ビットイメージ、32ビットでは同じ考え方)
-8を2の補数で表す
-8 = 1111 1000 (8ビット)
- 右に2ビットシフト(左端を0で埋める)
1111 1000 >>> 2 → 0011 1110
- 結果を10進数で見る
0011 1110 = 62
✅ ポイント:符号を無視して右にずらすので、負の数も大きな正の値になる。
実際のJavaの
intは32ビットなので、負の数>>>は非常に大きな正の値になります。
3. 図でまとめ(8ビット例)
| 元の数 | 二進数 | >> 2 | >>> 2 |
|---|---|---|---|
| 8 | 0000 1000 | 0000 0010 = 2 | 0000 0010 = 2 |
| -8 | 1111 1000 | 1111 1110 = -2 | 0011 1110 = 62 |
- 正の数は
>>と>>>で結果が同じ - 負の数は
>>は符号を維持、>>>は0埋めで正の値に変化
4. Javaで確認するコード
public class ShiftExample {
public static void main(String[] args) {
int a = 8;
int b = -8;
System.out.println("a >> 2 = " + (a >> 2));
System.out.println("a >>> 2 = " + (a >>> 2));
System.out.println("b >> 2 = " + (b >> 2));
System.out.println("b >>> 2 = " + (b >>> 2));
}
}
Java出力例(32ビット)
a >> 2 = 2
a >>> 2 = 2
b >> 2 = -2
b >>> 2 = 1073741822
b >>> 2は 1073741822 = 32ビットで右シフトしたときの符号なし正数b >> 2は -2 = 符号を維持
5. 覚え方のコツ(初心者向け)
>>:符号を維持する → 負の数も負のまま>>>:符号を無視 → どんな数も左端を0で埋めて正の値に- 正の数では両方同じ結果
💡 補足:
- フラグ管理やビット演算では
>>>は符号を気にせず扱いたいときに便利 - 整数の除算をビットで表す場合は、負の数には注意して
>>を使う
