二項演算による型変換 - 萌えJava超入門
第五章 演算子

二項演算による型変換

2つの項のデータ型が異なる場合には、データ型をそろえてから演算が行われます。
演算による型変換のルールを確認してみましょう。

目次


1. データ型はそろえて演算される

加減乗除及び剰余の計算は項(オペランド)が2つある「二項演算」です。
このような二項演算では、二つ項のデータ型をそろえてから計算が行われます。
計算結果のデータ型は、そろえられたデータ型で得られます。


データ型をそろえるのは
プログラムが勝手にやってくれる。
ただ、計算結果のデータ型を理解していないと
面倒なことになる。
int同士の割り算とかね。


2.二項演算による型変換

以下が、型変換のルールです。

二項演算による型変換
  1. どちらかの値が double の場合  → 他方の値も double に変換します
  2. どちらかの値が float の場合 → 他方の値も float に変換します
  3. どちらかの値が long の場合 → 他方の値も long に変換します
  4. いずれも該当しない場合 → 両方の値を int に変換します
    この規則は上から順に適用されます。
    一つ適用されれば、以降の処理は行われません。

byteとshortはintで計算
上述の(4.)のルールが適用されて、
byteと shortは intに型変換されてから計算されます。

byteと shortは、リテラルも intと共通だ。
慣れないうちは、intを使えばいいだろう。


3. int同士の計算

二つの項が同じなので型変換は起こりませんが、演算結果も intであることに注意してください。
割り算(/)の結果が小数になった場合、小数点以下が切り捨てられます

int同士の割り算
 int同士の演算では、結果もintで得られます。
 割り算(/)の結果は、小数点以下が切り捨てられます。

//Sample05_01.java
class Sample05_01 {
    public static void main(String[] args){
        int a_int = 2;
        int b_int = 5;
        int c_int = 8;
        System.out.println(a_int + b_int);
        System.out.println(c_int - b_int);
        System.out.println(a_int * c_int);
        System.out.println(c_int / a_int);
        System.out.println(b_int / a_int);//← 切り捨て発生
        System.out.println(b_int % a_int);
    }
}

コマンドライン
> javac Sample05_01.java
> java Sample05_01
7
3
16
4
2 ← 切り捨て発生 (2.5)
1

これ、慣れるしかないの?



慣れてるはずなのに
何故かハマる。
慣れるしかないのです。


4. double同士の計算

double同士の演算では、結果も doubleで得られます。
整数で割り切れない割り算でも、切り捨てられることはありません。(注)

注: 打切り誤差は普通にありますよぉ。
//Sample05_02.java
class Sample05_02 {
    public static void main(String[] args){
        double a_dou = 2.0;
        double b_dou = 5.5;
        double c_dou = 8.0;

        System.out.println(a_dou + b_dou);
        System.out.println(c_dou - b_dou);
        System.out.println(a_dou * c_dou);
        System.out.println(c_dou / a_dou);
        System.out.println(b_dou / a_dou);
        System.out.println(b_dou % a_dou);
    }
}

コマンドライン
> javac Sample05_02.java
> java Sample05_02
7.5
2.5
16.0
4.0
2.75
1.5


割り算の切り捨て問題は
doubleにはないのね。
その通り。
ただ、doubleや floatを扱ってみると、
妙な誤差が現れる場合がある。
そんな時は、以下のリンクを参考にしてくれ。

本章で説明いたします。
   お急ぎの方はこちらからどうぞ→ 浮動小数点型の誤差



5. intとdoubleの計算

doubleと intの演算では、結果は doubleで得られます。
割り切れない割り算でも、切り捨てられることはありません。

//Sample05_03.java
class Sample05_03 {
    public static void main(String[] args){
        int a_int = 2;
        int b_int = 5;
        int c_int = 8;

        double a_dou = 2.0;
        double b_dou = 5.0;
        double c_dou = 8.0;

        System.out.println(a_int + b_dou);
        System.out.println(c_dou - b_int);
        System.out.println(a_dou * c_int);
        System.out.println(c_int / a_dou);
        System.out.println(b_dou / a_int);
        System.out.println(b_dou % a_int);
    }
}

コマンドライン
> javac Sample05_03.java
> java Sample05_03
7.0
3.0
16.0
4.0
2.5
1.0

intとdoubleの計算
 intと doubleの演算では、intの項doubleに変換してから
 double同士の演算として処理されます。
 結果も doubleで得られます。

doubleが片方に入っていれば
doubleで計算されるのね。
その通り。


6. 演算の順番に注意

intとdoubleが混在する場合には、演算の順番に注意してください。
先に、int同士の割り算が計算されると、切り捨てが発生します。

//Sample05_05.java
class Sample05_05 {
    public static void main(String[] args){
        int a_int = 2;
        int b_int = 5;
        int c_int = 8;

        double a_dou = 2.0;
        double b_dou = 5.0;
        double c_dou = 8.0;

        System.out.println(c_dou + b_int / a_int);
        System.out.println(c_int + b_int / a_dou);
    }
}

コマンドライン
> javac Sample05_05.java
> java Sample05_05
10.0 ← 切り捨て発生
10.5

b_int / a_int は int同士の演算なので、計算結果も intです。
ここで切り捨てが発生して、5/2=2 となります。

doubleが含まれていても、演算子の優先順位によっては切り捨てが起こることに注意してください。

doubleが入っているからといって
油断できないんスね~。
だな。
こういうのが
バグになりやすい。


お疲れ様でした。




© 2019 awasekagami