演算の時の型変換ルール

広告

今までは「=」を使った代入演算が行われる時の型変換について見てきました。ここでは「+」や「*」など2つの値を対象とした二項演算の際の型変換ルールについて確認します。

型変換は次の規則に従います。

(1) どちらかの値がdouble型の場合は他の値をdouble型に変換する
(2) どちらかの値がfloat型の場合は他の値をfloat型に変換する
(3) どちらかの値がlong型の場合は他の値をlong型に変換する
(4) (1)から(3)に該当しない場合は両方の値をint型に変換する

この規則は(1)から順に適用され、いずれかに適用されればその後の変換は行われません。例えばdouble型とlong型の値の演算では、long型の値がdouble型に変換されて演算が行われます。

次の例を見てください。

double d = 12.345;
long l = 3220L;

double val = d * l;

上記ではdouble型の変数「d」とlong型の変数「l」が「*」演算子によって演算さえる際、まずlong型の変数「l」がdouble型に変換された後で演算が行われます。結果として「d * l」はdoule型となりその後で「=」演算子によって左辺の変数「val」に代入されます。

もう1つ例を見てみます。

int i = 83;
double d = 12.345;
long l = 3220L;

double val = d + i * l;

複数の演算子が組み合わされた場合も演算子の優先順位に従って順に演算が行われます。まず「i * l」が行われますが演算が行われる前に変数「i」がlong型に変換されます。結果として「i * l」はlong型の値となります。次に「d」と「i * l」の演算が行われますが演算が行われる前に「i * l」の結果がdouble型に変換されます。結果として「d + i * l」はdouble型の値となります。

int型への変換に伴う注意点

double型、float型、long型に該当しない値は全てint型に変換されてから演算が行われます。つまりshort型とshort型の演算を行う場合もどちらの値もいったんint型に変換されてから演算が行われると言う事です。

次の例を見てください。

short s1 = 10;
short s2 = 9;

short val = s1 + s2;

一見するとshort型とshort型の値を演算した結果をshort型の変数に代入しているので問題無いように見えますが、コンパイルすると「精度が落ちている可能性」というコンパイルエラーが表示されます。

これは演算子の対象の値がどちらもdouble型、float型、long型に該当しませんので、演算が行われる前にどちらの値もint型に変換されてから演算が行われます。結果として「s1 + s2」はint型の値となります。int型の値をshort型の値に代入する場合はキャスト演算子が必要となるためコンパイルエラーが発生します。

正しくは次のように記述する必要があります。

short s1 = 10;
short s2 = 9;

short val = (short)(s1 + s2);

なぜエラーとなっているか分かりにくい箇所なので注意して下さい。

単項マイナス演算子の注意点

単項マイナス演算子を使うことで符号を反転することができます。(詳しくは「単項マイナス演算子」を参照して下さい)。

int n1, n2;

n1 = 10;
n2 = -n1;

ただしbyte型、short型、char型に対して単項マイナス演算子を使用する時は注意が必要です。byte型、short型、char型の場合には符号を反転させる前に対象の値をint型へ自動的に型変換するためです。その為、次のような記述を行うとコンパイル時に「精度が落ちている可能性」というコンパイルエラーが表示されます。

short s1 = 10;
short s2 = -s1;

これは単項マイナス演算子によって「s1」がint型へ変換され、結果的に「-s1」がint型の値になっているためです。int型の値をshort型の値に代入する場合はキャスト演算子が必要となります。

正しくは次のように記述する必要があります。

short s1 = 10;
short s2 = (short)-s1;

これも分かりにくいエラーが発生するところなので注意して下さい。

サンプル

では簡単な例で試しておきます。

JSample5_1.java

class JSample5_1{
  public static void main(String args[]){
    double d1 = 7.0;
    int i1 = 7;
    int i2 = 3;

    System.out.println(d1 / i2);
    System.out.println(i1 / i2);
  }
}

コンパイル後に実行すると次のように表示されます。

p5-1

( Written by Tatsuo Ikura )

関連記事 (一部広告含む)