基本的な事ですが、byte[]を使う必要に迫られました、、
個人的にとても苦手な所なので、克服するために1つずつJavaの「byte」について調べてみました。
まず「wiki」を見てみました。
Javaのbyteはintやshort等と同じ基本型といわれるもので、
その中でも整数型として提供されているようです。
符号付きの8bitで1000 0000 (-128) 〜 0111 1111 (+127)まで表現できます。
型 | デフォルト値 | サイズ | 範囲 |
---|---|---|---|
byte | 0 | 8bit符号付き | -128〜127 |
あとはどんどん色々な使い方を試して探っていくこととします。
以下はbyte型の変数に整数の127を代入して出力するコードです。
public class TestByte { public static void main(String[] args) { // Javaのbyte型 // 10000000 01111111までを表現可能 // 整数型の為、値は10進数で保持します。 byte bval = 127; System.out.println(bval); } } //[実行結果] 127
「127」が表示されました、「byte」の名前に惑わされましたが整数型ですもんね。
ちなみにbyte型の扱える範囲以上の128を代入しようとするとエラーになります。
クイックフィックスが型をintに変えるかい? それとも128を(byte)でキャストするかい?と聞いてきます。
ちなみに強引に以下のようにキャストすると、
byte bval = (byte) 128;
System.out.println(bval);
[実行結果] -128
「-128」が表示されました。129を代入すると「-127」が表示され、
1ずつ増えていきます。127を超える表示になったら-128に戻り、
127〜-128の範囲内でこれを延々と繰り返すようです。
次は整数の「127」をIntegerクラスのメソッドで2進数と16進数形式で出力してみました。
public class TestByte { public static void main(String[] args) { // 10進数127の場合、2進数では 0111 1111になる // 0111は 16進数で7、1111は 16進数でfになる。 // 出力は7fになる。 byte bval1 = (byte)127; System.out.println("(byte)127を出力"); System.out.println("10進数表現:"+ bval1); System.out.println("2進数表現:"+Integer.toBinaryString(bval1)); System.out.println("16進数表現:"+Integer.toHexString(bval1)); System.out.println("16進数表現2桁:"+String.format("%02x", bval1)); } }
[実行結果]
(byte)127を出力
そのまま出力(10進数表現):127
2進数表現:1111111
16進数表現:7f
16進数表現2桁:7f
toBinaryStringの結果で最上位ビットが「0」の場合は省略されて7桁になってますね。
上記のコードを少し変えて、負の値「-4」を代入すると、
byte bval1 = (byte)-4; System.out.println("(byte)-4を出力"); System.out.println("10進数表現:"+ bval1); System.out.println("2進数表現:"+Integer.toBinaryString(bval1)); System.out.println("16進数表現:"+Integer.toHexString(bval1)); System.out.println("16進数表現2桁:"+String.format("%02x", bval1));
こんな結果になります。1がいっぱい
[実行結果]
(byte)-4を出力
10進数表現:-4
2進数表現:11111111111111111111111111111100
16進数表現:fffffffc
16進数表現2桁:fc
toBinaryStringのJavaDocを確認すると以下のように書いてあります。
2の32乗を加算した結果、1が埋められたようです。
http://java.sun.com/j2se/1.5.0/ja/docs/ja/api/java/lang/Integer.html#toBinaryString(int)
整数の引数の文字列表現を、基数 2 の符号なし整数として返します。
引数が負の数の場合は、符号なし int 値は引数に 2の32乗を加算した値になります。そうでない場合は、引数に等しい値になります。この値は、2 進数 (基数 2) の ASCII 文字列に変換されます。前に 0 は付きません。符号なしの絶対値がゼロの場合は、単一のゼロ文字「0」(「\u0030」) で表されます。そうでない場合は、符号なしの絶対値を表す文字の 1 文字目はゼロではありません。2 進数の桁には、「0」(「\u0030」) および「1」(「\u0031」) が使用されます。
byte型は8進数、16進数のリテラルを代入することもできます。
試しに10進数で153を表す0x99を代入してみます。
// 16進リテラルも代入可能 // 0x99を代入した場合、10進数では153となるが、 // byte型の扱える範囲を超えるのでそのままだと負の値が出力される。 byte bval1 = (byte)0x99; System.out.println("(byte)0x99を出力"); System.out.println("10進数表現:"+ bval1); System.out.println("2進数表現:"+Integer.toBinaryString(bval1)); System.out.println("16進数表現:"+Integer.toHexString(bval1)); System.out.println("16進数表現2桁:"+String.format("%02x", bval1));
出力時にはbyteで扱える範囲を超えているので負の値が表示されてしまいます。
[実行結果]
(byte)0x99を出力
10進数表現:-103
2進数表現:11111111111111111111111110011001
16進数表現:ffffff99
16進数表現2桁:99
これを10進数153として表示するには以下のようにします。
System.out.println(bval1 & 0xff);
上記は何をしてるかというと、
変数「bval1」と正の整数255を表す16進数リテラル「0xff」のAND演算をして、
正の値に変換しています。
11111111 11111111 11111111 10011001 (bval1)
00000000 00000000 00000000 11111111 (0xff ) AND
- -
00000000 00000000 00000000 10011001 結果 正の値に戻る。
あとはこれが単純に配列になっただけなので、こんな感じに利用できます。
byte bval1[] = { (byte)0x77, (byte)0x88, (byte) 0x99 }; System.out.println("bval1[]を出力"); for(int i=0; i < bval1.length ; i++){ System.out.println("10進数表記:"+ (bval1[i] & 0xff)); //System.out.println("16進数表記"+ String.format("0x%02x", bval1[i])); }