Java | 負の数を右シフトしたときに符号をどう保つか

Java Java
スポンサーリンク

では、右シフト演算で負の数がどう扱われるかを図で丁寧に解説します。Javaの >>>>> の違いも含めて、初心者向けに段階的に説明します。


1. 符号付き右シフト >>(Arithmetic Shift Right)

  • 目的:ビットを右にずらす
  • 特徴:左端(最上位ビット)は 符号ビットを維持
    • 正の数なら左端に0を入れる
    • 負の数なら左端に1を入れる
  • 結果:負の数は負のままシフトされる

例:-8 >> 2(8ビットイメージ)

  1. -8 を2の補数で表す
-8 = 1111 1000  (8ビット)
  1. 右に2ビットシフト(符号ビットを維持)
1111 1000 >> 2 → 1111 1110
  1. 結果を10進数で見る
1111 1110 = -2

✅ ポイント:負の数でも符号を保持するので、-8 / 4 = -2 と同じ結果になります。


2. 符号なし右シフト >>>(Logical Shift Right)

  • 目的:ビットを右にずらす
  • 特徴:左端は 常に0 で埋める
  • 結果:負の数も正の大きな値に変わることがある

例:-8 >>> 2(8ビットイメージ、32ビットでは同じ考え方)

  1. -8 を2の補数で表す
-8 = 1111 1000  (8ビット)
  1. 右に2ビットシフト(左端を0で埋める)
1111 1000 >>> 2 → 0011 1110
  1. 結果を10進数で見る
0011 1110 = 62

✅ ポイント:符号を無視して右にずらすので、負の数も大きな正の値になる。

実際のJavaの int は32ビットなので、負の数 >>> は非常に大きな正の値になります。


3. 図でまとめ(8ビット例)

元の数二進数>> 2>>> 2
80000 10000000 0010 = 20000 0010 = 2
-81111 10001111 1110 = -20011 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で埋めて正の値に
  • 正の数では両方同じ結果

💡 補足:

  • フラグ管理やビット演算では >>> は符号を気にせず扱いたいときに便利
  • 整数の除算をビットで表す場合は、負の数には注意して >> を使う
タイトルとURLをコピーしました