キャスト (型変換)


今回は「キャスト」についてみていきます。
「キャスト」とはあるデータ型を他のデータ型に変換することです。前回に代入には「左辺の方が表現範囲が大きくなくてはいけない」という制約があることを記事にしました。例えばint型の変数にdouble型の値を代入することはできません。int型よりdouble型の方が表現範囲が大きいのでエラーになります。このような場合に、double型の値を意図的に「int型に変換」して代入可能なようにするなどで利用できます。

キャストの記述

(変換したい型) 値

変数やリテラルの前に小括弧で変換したい型を囲んで記述します。例えば変数x を int型にキャストしたい場合は「 (int) x 」のように記述します。

サンプルコード

public class sample {
    public static void main(String[] args) {
        byte a;
        int  b = 10;
        a = b;
    }
}

データ表現範囲の大きいものから並べてみます。

double > float > long > int > short > byte

byte型よりint型の方が表現範囲が大きいです。サンプルコードでは byte型の変数a にint型の変数bの値を代入しようとしています。10という値はbyte型でも表現できるのですが、「データ型が左辺の方が表現範囲が大きくなくてはいけない」という制約によりエラーになります。

eclipse では次のようにエラーメッセージがでました。

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
型の不一致: int から byte には変換できません

public class sample {
    public static void main(String[] args) {
        byte a;
        int  b = 10;
        a =  (byte) b;
    }
}

5行目で (byte) b とキャストします。変数bはint型からbyte型に変換されました。byte型の変数a にbyte型の変数bを代入するのでエラーになりません。

キャストの問題点

キャストにより変換後の方が表現範囲が小さくなる場合に注意が必要です。変換前のデータを表現できない場合におかしなデータになります。処理上、溢れた部分は切り捨てられます。

public class sample {
    public static void main(String[] args) {
        byte a;
        double  b = 12.345;
        a =  (byte) b;
        System.out.println( a );  //結果12
    }
}

double型をbyte型に変換しています。doubleは浮動小数点型の1つなので小数点以下も表現できます。byteは整数型の1つなので整数しか表現できません。浮動小数点型から整数型に変換した場合は小数点以下は切り捨てられ整数になります。

public class sample {
    public static void main(String[] args) {
        byte a;
        short  b = 128;
        a =  (byte) b;
        System.out.println( a );  //結果 -128
    }
}

byte型の表現範囲は「-128~127」です。表現範囲を超えた「128」の値の変数をキャストすると「-128」と負数になりました。

java044

128は2進数では「10000000」になります。byte型は8bitなので最上位である8bit目は符号用ビットです。キャストでshort型からbyte型に変換したことにより最上位が「1」になってしまい符号が変わります。Javaは負数を「2の補数」で処理しているので2進数の「10000000」は-128になります。

public class sample {
    public static void main(String[] args) {
        byte a;
        short  b = 256;
        a =  (byte) b;
        System.out.println( a );  //結果 0
    }
}

上記サンプル「128」は2進数でも8bitの範囲で処理できます。次は9bit目に「1」がある256をキャストするとどうなるかみてみます。

java045

結果は「0」になります。キャスト後に溢れた部分は切り捨てられ無視されているのがわかります。
このようにキャストする場合は、符号ビットに影響しないか、溢れた部分が切り捨てられて予想外の値にならないか十分注意が必要になります。


「キャスト (型変換)」への2件のフィードバック

  1. はじめまして。javaのbyte型の事を調べていてたどり着きました。

    今javaを使ってRS232Cとの通信のやりとるするプログラムを作成しているのですが、そこでまさしく記事のようなことが起こっています。
    0x80をbyte型に代入しようとすると-128となってしまっているのです。
    上記のことを読むと理解は出来るのですが、どうしても128をセットしたいのですが、javaの仕様上不可能なのでしょうか?

    RS232Cでシリアル通信をする際にSTXやETX等固定の値を取って送信しますよね。
    その送信する型がbyte型で送信内容をbyte型で作成しています。
    byte[] dat;

    dat = new byte[21];
    dat[0] = 0x10; //DLE
    dat[1] = 0x2; //STX
    dat[2] = Byte.parseByte(dt_Size_H); //データ長(H)
    dat[3] = Byte.parseByte(dt_Size_L); //データ長(L)
    dat[4] = 0xB;
    dat[5] =(byte) 0x80;
    dat[6] = 0x50;
    —-と続いていきます。

    そして出来たdatを下記で送信しています。
    outputStream.write(dat);
    outputStream.flush(); // 送信を確立

    ここでいうdat[5]が0x80の固定値をセットしないといけないのです。
    いろいろサイトを参考にして
    System.out.println(b) というようなことをしたら良いとかあるみたいですが、実際にはbyte型に代入するので結局-128になってしまうのです。

    どう考えても無理なんでしょうか??

    お忙しいとは思いますがご教授のほどよろしくお願いいたします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です