Java | 単項マイナス演算子

Java Java
スポンサーリンク

初心者向けにやさしく、例題つきで詳しく説明します。実際の Java コード例を交えて、動作のしくみ・落とし穴・練習問題(解答付き)まで用意します。

単項マイナス演算子(-)とは?

  • 値の「符号(正/負)」を反転させる演算子です。
    例:10-10-55
  • 対象(オペランド)が 1つだけ のため「単項」演算子と呼びます。
  • Java には対応する単項プラス演算子(+)もありますが、ほとんど何もしません(符号をそのままにするだけ)。

基本の使い方(コード例)

int a = 10;
System.out.println(-a);   // -10

double b = -3.5;
System.out.println(-b);   // 3.5

int c = -7;
System.out.println(-c);   // 7

System.out.println(+a);   // 10 (単項プラス、ほぼ何もしない)
Java

型ごとの注意点(初心者がつまずきやすいポイント)

1) byte・short に適用すると型が int に“昇格”する

  • Java では算術演算で byteshortint に自動変換されます。
  • つまり -b の結果は int 型になります。
byte b = 5;
System.out.println(-b);   // -5 (出力は int として扱われる)
byte bb = -b;             // コンパイルエラー:型不一致(int → byte)
byte bb2 = (byte)-b;      // 明示的キャストすれば OK
Java

ポイントbyteshort を再代入するときはキャストが必要です。


2) char(文字型)にも使える

  • char は内部的に数値(Unicodeコードポイント)なので、- を使うと数値に変換されて負の整数になります。
char ch = 'A';            // 'A' は 65
System.out.println(-ch);  // -65
Java

3) 整数のオーバーフロー(特に Integer.MIN_VALUE)

  • int の最小値 Integer.MIN_VALUE(−2,147,483,648)を符号反転すると、表現できる +2,147,483,648 が int にないため 同じ値が返る(オーバーフロー)
int min = Integer.MIN_VALUE;
System.out.println(min);      // -2147483648
System.out.println(-min);     // -2147483648 ← 期待どおり +2147483648 にはならない
Java

なぜ? Java の int は 32-bit 二の補数表現で、正の最大値は 2,147,483,647。符号反転で範囲外になり、結果として同じ最小値に戻る(オーバーフロー)します。長い計算や絶対値を取るときに注意が必要です。

オーバーフローのビジュアル解説


4) 浮動小数点(float / double)では -0.0 が存在する

  • 浮動小数点では -0.0 という概念があります。-0.0 == 0.0true になりますが、1.0 / -0.0-Infinity などになるので挙動が特異。
double z = -0.0;
System.out.println(z == 0.0);   // true
System.out.println(1.0 / z);    // -Infinity
Java

ポイント:0 の符号に敏感な数値計算(物理シミュレーションなど)は特に注意。


5) ブール(boolean)には使えない

  • boolean は数値ではないので -true のような使い方はできません(コンパイルエラー)。

優先順位(どの順で計算されるか)

  • 単項演算子は多くの二項演算子よりも優先されます。
    例:-a * b(-a) * b と同じです(- が先に作用する)。

よくある間違い(&対処)

  • byte を直接 - して別の byte へ代入 → コンパイルエラー(キャスト忘れ)。
    → 解決:byte result = (byte)-b;
  • Integer.MIN_VALUE- して絶対値を期待する → オーバーフローで失敗。
    → 解決:long に拡張してから反転する、または Math.abs の結果を注意深く扱う(Math.abs(Integer.MIN_VALUE)Integer.MIN_VALUE を返す)。
  • --= を混同する(x -= yx = x - y)。-x は「x の符号を反転」するだけ。

具体的な例題(覚えるための実践)

例題1:単純な符号反転

int x = 20;
System.out.println(-x);   // 出力: -20
Java

例題2:byte の扱い

byte b = 2;
System.out.println(-b);            // 出力: -2 (int として出力)
byte result = (byte)-b;
System.out.println(result);        // 出力: -2 (castでbyteに戻した)
Java

例題3:char への適用

char c = 'B';   // 'B' は 66
System.out.println(-c);  // 出力: -66
Java

例題4:Integer.MIN_VALUE の罠

int min = Integer.MIN_VALUE;
System.out.println(min);    // -2147483648
System.out.println(-min);   // -2147483648 ← 期待しない結果になる
Java

例題5:浮動小数点の -0.0

double z = -0.0;
System.out.println(z == 0.0);   // true
System.out.println(1.0 / z);    // -Infinity
Java

練習問題(初心者向け)— 解答・解説付き

問題1

int a = 5;
int b = -a;
System.out.println(b);
Java

解答-5
解説-a が 5 → -5 に反転。

問題2

byte x = 10;
byte y = -x;  // コンパイルされますか?
Java

解答コンパイルエラーになる(型不一致)。
解説-xint 型になるため、byte に直接代入できない。byte y = (byte)-x; とキャストすれば OK。

問題3

int v = Integer.MIN_VALUE;
System.out.println(-v == v);
Java

解答true
解説Integer.MIN_VALUE- しても範囲オーバーフローにより同じ値になるため同一。

問題4

double d = -0.0;
System.out.println(d == 0.0);
System.out.println(1.0 / d);
Java

解答
true
-Infinity
解説:浮動小数点では -0.00.0 は等しいが、除算で符号が影響して -Infinity になる。

問題5

char ch = 'C';
System.out.println(-ch + 1);
Java

解答-67 + 1-66 の結果(実際に出力は -66)。
解説'C' は 67、-ch-67、そこに +1-66


まとめ(覚えておくこと)

  • -x は x の符号を反転する単純な演算子。とても基本的。
  • ただし型の昇格(byte/shortint)、Integer.MIN_VALUE のオーバーフロー、浮動小数点の -0.0 など落とし穴がある。
  • 実際にコードを書いて System.out.println() で出力を確認すると理解が速いです。
タイトルとURLをコピーしました