技術メモ

神奈川在住のITエンジニアの備忘録。おもにプログラミングやネットワーク技術について、学んだことを自分の中で整理するためにゆるゆると書いています。ちゃんと検証できていない部分もあるのでご参考程度となりますが、誰かのお役に立てれば幸いです。

byte型とint型の変換

以前、Javaのbyte型とint型との変換について勉強するために作成したテストコード。

public class TestByte {

    public static void main(String[] args) {

        // Test1
        byte byteData = (byte) 0xC7;  // 11000111
        // If there is no "(byte)", 0xC7 is looked as int.
        System.out.println(byteData); // -57

        // Test2
        int intData =  0xC7;         // 00000000 00000000 00000000 11000111
        System.out.println(intData); // 199

        // Test3
        int castedData = (int)byteData; // 11111111 11111111 11111111 11000111
        System.out.println(castedData); // -57

        // Test4
        int positiveNumber = byteData & 0xff; // 11111111 11111111 11111111 11000111 & 00000000 00000000 00000000 11111111
        // 0xff is looked as int, so this is "int" & "int".
        // Result: 00000000 00000000 00000000 11000111
        System.out.println(positiveNumber);   // 199
    }
}
  • Test1: 0xC7 は、byte型だと先頭bitが立っているので、Javaにより負数と解釈される。なお、(byte)のキャストがないと、0xC7はint型と扱われ byteData への代入の際にコンパイルエラーとなる。
  • Test2: 0xC7 は、int型だと先頭bitが立っていないので、Javaにより正数と解釈される。
  • Test3: 先頭bitが立っているbyte型のデータをint型にキャストすると、拡張された上位bitが全て 1 で埋められ、Javaにより負数と解釈される。
  • Test4: byte型のデータをintで(暗黙的に)キャストする際、0xff とのANDを取ると、拡張された上位bitは全て 0 で埋められ、Javaにより正数と解釈される。


ソース解析を行っていて、久々に出くわすと、あれ何だっけ・・?と思ってしまうことがあるので、、ここに纏めてみた。

要は、明示的にも暗黙的にも、byte型をint型にキャストする場合、拡張された上位bitが全て 1 で埋まることがあるので、要注意ということ。これは、byte→int に限らず、型を大きい方向に拡張すると起きる。
普通に数値計算する範囲では問題にはならないと思うが、バイト列を16進ダンプ文字列に変換する処理を書くときなどは、知らないとはまると思う。