2019.07.09

Javaプログラミング

byte型をint型へ

Javabyte型の値の範囲は-128~127です。ここでは、byte型ビットの並びから値の範囲を"-128~127"から"0~255"に変換し、int型変数に格納する方法を説明します。byte型変数に格納されている8ビットの列をそのまま10進数にした値をint型変数に格納することで0から255の値に変換します。

それでは、変換方法について説明していきましょう。

まず、下の表をみてください。これはbyte型ビット列とその値、byte型の値を変換した後のint型の値をまとめたものです。

byteのビット列 byteの値 変換後の値(目標)
00000000 0 0
00000001 1 1
00000010 2 2
00000011 3 3
01111101 125 125
01111110 126 126
01111111 127 127
10000000 -128 128
10000001 -127 129
10000010 -126 130
11111101 -3 253
11111110 -2 254
11111111 -1 255

この表から、byte型ビット列"00000000"(0)から"01111111"(127)までは、ビット列の2進数byteの値が一致していることが分かります。

byte型ビット列"10000000"からbyte型の値がマイナスの値になっていることがわかります。一般的に2進数の"10000000"は10進数の128を表しますが、Javabyte変数の場合には"-128"になっています。

ビット列"10000000"以降のbyte型の値が変換後のintの値と一致しないので、これを一致させるプログラムを作成します。

ここから、byte型int型に変換するプログラムを紹介していきます。

Javaソースコード その1

このソースコードは、byte型の8ビットから10進数の値を求める方法を使っています。各ビット毎にAND演算することで、ビットが0か1かを判定しています。

BytetoInt1.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
public class BytetoInt1 {
	// byteのビットの並びでintに変換
	public static int BytetoInt( byte b )
	{
		int i;

		i = 0;
		// 8ビット目が1かどうか
		if ( 0 != ( 0x80 & b ) ) i += 128;
		// 7ビット目が1かどうか
		if ( 0 != ( 0x40 & b ) ) i +=  64;
		// 6ビット目が1かどうか
		if ( 0 != ( 0x20 & b ) ) i +=  32;
		// 5ビット目が1かどうか
		if ( 0 != ( 0x10 & b ) ) i +=  16;
		// 4ビット目が1かどうか
		if ( 0 != ( 0x08 & b ) ) i +=   8;
		// 3ビット目が1かどうか
		if ( 0 != ( 0x04 & b ) ) i +=   4;
		// 2ビット目が1かどうか
		if ( 0 != ( 0x02 & b ) ) i +=   2;
		// 1ビット目が1かどうか
		if ( 0 != ( 0x01 & b ) ) i +=   1;

		return i;
	}


	// メイン
	public static void main( String[] args ) {
		// 変数を宣言
		byte b;
		int  i;

		// バイトの値 1
		b = 1;
		i = BytetoInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 127
		b = 127;
		i = BytetoInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 -1
		b = -1;
		i = BytetoInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 -128
		b = -128;
		i = BytetoInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
	}
}

BytetoInt1の出力結果

byte: 1
int : 1

byte: 127
int : 127

byte: -1
int : 255

byte: -128
int : 128

byte型の値が符号無しのint型に変換できています。

ここで、ソースコードの中のbyte型int型に変換するメソッドについて説明します。

002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
	// byteのビットの並びでintに変換
	public static int BytetoInt( byte b )
	{
		int i;

		i = 0;
		// 8ビット目が1かどうか
		if ( 0 != ( 0x80 & b ) ) i += 128;
		// 7ビット目が1かどうか
		if ( 0 != ( 0x40 & b ) ) i +=  64;
		// 6ビット目が1かどうか
		if ( 0 != ( 0x20 & b ) ) i +=  32;
		// 5ビット目が1かどうか
		if ( 0 != ( 0x10 & b ) ) i +=  16;
		// 4ビット目が1かどうか
		if ( 0 != ( 0x08 & b ) ) i +=   8;
		// 3ビット目が1かどうか
		if ( 0 != ( 0x04 & b ) ) i +=   4;
		// 2ビット目が1かどうか
		if ( 0 != ( 0x02 & b ) ) i +=   2;
		// 1ビット目が1かどうか
		if ( 0 != ( 0x01 & b ) ) i +=   1;

		return i;
	}

byte型int型に変換するメソッドです。8行目から23行目でビットの判定を行っています。判定に使っている"0x"で始まる値は16進数の値で、2進数では以下のようになります。

0x80は、8ビット列で"10000000"、10進数で128

0x40は、8ビット列で"01000000"、10進数で64

0x20は、8ビット列で"00100000"、10進数で32

0x10は、8ビット列で"00010000"、10進数で16

0x08は、8ビット列で"00001000"、10進数で8

0x04は、8ビット列で"00000100"、10進数で4

0x02は、8ビット列で"00000010"、10進数で2

0x01は、8ビット列で"00000001"、10進数で1

ビット列の左端にある1が、1つずつ右にずれていっていることが分かります。

上記の8つの値と元のbyteの値のAND演算をすることでビットの有無を検出することができます。AND演算は、両方のビットが1の場合だけ1になります。

AND

例えば、0x80("10000000")と"10100001"のAND演算の結果は"10000000"となります。これは2つの値をビット単位で比べたとき、両方が1のビットは1番左だけであるためです。

その他、0x80("10000000")と"01111111"のAND演算の結果は"00000000"となります。これは2つの値をビット単位で比べたとき、両方が1のビットが無いためです。

このように各ビットが0か1かは、AND演算を使うことで実現できます。

ビットが1の時に10進数の値を足していけば、ビット列を10進数にした値が得られます。

Javaソースコード その2

このソースコードは、Java 8以降で使えるByte.toUnsignedIntメソッドを利用したものです。

Byte.toUnsignedIntは、byte型の値を引数として渡して、符号無しのint型の値を戻すものです。メソッドを呼ぶだけでビット列に対応するint型の値に変換できます。

BytetoInt2.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
public class BytetoInt2 {
	public static void main( String[] args ) {
		// 変数を宣言
		byte b;
		int  i;

		// バイトの値 1
		b = 1;
		i = Byte.toUnsignedInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 127
		b = 127;
		i = Byte.toUnsignedInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 -1
		b = -1;
		i = Byte.toUnsignedInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 -128
		b = -128;
		i = Byte.toUnsignedInt( b );
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
	}
}
byte: 1
int : 1
	
byte: 127
int : 127
	
byte: -1
int : 255
	
byte: -128
int : 128

結果は、ビット列のAND演算するBytetoInt1.javaで得た結果と同じになりました。

Javaソースコード その3

このソースコードは、byteの値と0xff("11111111")のAND演算を行い、符号無しのint型の値に変換するものです。

BytetoInt3.java

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
public class BytetoInt3 {
	public static void main( String[] args ) {
		// 変数を宣言
		byte b;
		int  i;

		// バイトの値 1
		b = 1;
		i = b & 0xff;
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 127
		b = 127;
		i = b & 0xff;
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 -1
		b = -1;
		i = b & 0xff;
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
		System.out.println();

		// バイトの値 -128
		b = -128;
		i = b & 0xff;
		System.out.println( "byte: " + b );
		System.out.println( "int : " + i );
	}
}
byte: 1
int : 1
	
byte: 127
int : 127
	
byte: -1
int : 255
	
byte: -128
int : 128

結果は、BytetoInt1.javaとBytetoInt2.javaで得た結果と同じになりました。

ここで、ソースコードの中のbyte型int型に変換するソースについて説明します。

028
029
030
		// バイトの値 -128
		b = -128;
		i = b & 0xff;

byte型の値を符号無しのint型に変換するソースコードです。

i = b & 0xffを計算する過程で変数bの値がint型と同じ32ビットに拡張され、その値と0xff("0000000 00000000 000000000 11111111")のAND演算が行われます。

このソースの場合、b = -128は、8ビットの"10000000"から32ビットの"0000000 00000000 000000000 10000000"に拡張され、その値と0xff("0000000 00000000 000000000 11111111")のAND演算が行われます。

演算の結果、変数iビット列は"0000000 00000000 000000000 10000000"となります。これは、10進数で128です。

次に読んでほしいコンテンツ

数値を2進数で表したときの各桁の「0」と「1」に対して演算を行えます。4種類の演算、AND(論理積)、OR(論理和)、XOR(排他的論理和)、NOT(否定)を詳しく説明しています。

2016.03.26

「0」と「1」の2つの数字で表される2進数(バイナリ)。一般に使われている10進数に変換するには。

2016.02.16

プログラミングで使う変数って何?

2020.03.23

広告