- PR -

byteからintへの変換に関して

1
投稿者投稿内容
未記入
会議室デビュー日: 2007/10/20
投稿数: 3
投稿日時: 2007-10-20 01:32
byteからintの変換に関して下記のように変換しています。

---------ソース---------
1 byte b = (byte)0xc7;
2 System.out.println(b & 0xff);

---------実行結果---------
0xC7

---------質問---------
ソース2行目の”& 0xff”をつける理由が分かりません。
どなたか教えていただけませんか。

---------現在分かっている事---------
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?forum=12&topic=25149より
> (1) b は byte型、リテラル 0xFF は int型なので、
> 論理積を計算する前に b が暗黙のキャストにより int型になります。

> (2) b に格納されている値 0xC7 (-57) が 0xFFFFFFC7 (-57) になります。
> -57 という値は変化しませんが、byte から int に変換されたことによりビットパターンが変化します。
> 負数の場合は、増えた桁数を 2進数の 1 で埋めなければならないので。

> (3) リテラル 0xFF は int型なので、桁数が分かりやすいように表記すると 0x000000FF となります。

> (4) 0xFFFFFFC7 & 0x000000FF の論理積を取るので結果が 0x000000C7 になります。

との記載がありました。

(2)の部分が分かりません。
何故、 0xC7 (-57) が 0xFFFFFFC7 (-57) になるのでしょうか。

よろしくお願いします。
未記入
会議室デビュー日: 2007/10/20
投稿数: 1
投稿日時: 2007-10-20 02:03
よく見てないけど、
> 論理積を計算する前に b が暗黙のキャストにより int型になります。
が答えなんじゃないの・・・?
byte型が1バイトでint型が4バイトだからってだけじゃ?
朝日奈ありす
大ベテラン
会議室デビュー日: 2007/05/02
投稿数: 189
お住まい・勤務地: 最北の地
投稿日時: 2007-10-20 08:50
 0のビットパターン:00000000
 1のビットパターン;00000001
−1のビットパターン:11111111

コンピューターは実は足し算しかできません。
足し算を組み合わせて4則演算を行っています。

1−1の場合

00000001
+ 11111111
----------
100000000

となり

100000000は9桁なので8桁にする必要があります。
先頭「1桁」が削除されます。
よって
00000000 となり 1−1 = 0となります。

ここら辺のくだりだけでわかるかな?
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-10-20 10:39
最初にSystem.out.printlnの仕組みを把握する必要がありますね。

System.outはSystemクラスのstaticフィールドで、PrintStream型ですから
printlnというのはPrintStreamのメソッドになります。
PrintStreamにはprintlnのオーバーロードが多数存在するのですが、
http://java.sun.com/javase/ja/6/docs/ja/api/java/io/PrintStream.html
これらのオーバーロードの中にbyteを引数にとるものがありません。

byte -> intは暗黙に変換できるので、キャスト演算子なしに代入できます。
そこで、println()の引数にbyteを渡した場合、引数がintのメソッドが
呼び出され渡したbyteがintに拡張変換されることになります。

ここで(2)のbyteからintへの変換が起きている。
つまり、処理の実際は
コード:
byte b = (byte)0xc7;
int temp = b;  // intに拡張 0xFFFFFFC7
System.out.println(temp);  // println(int)の呼び出し


というように行われる。

あとは、byteからintに拡張するときに負号が維持されて拡張される
ことを理解すれば(これはすでに回答がありますね)
理解できるのではないでしょうか。
未記入
会議室デビュー日: 2007/10/20
投稿数: 3
投稿日時: 2007-10-20 10:40
未記入 さん
朝日奈ありす さん

解答ありがとうございます。

未記入 さん
申し訳御座いません。
説明不足でしたが、
(1)(3)(4)の説明は理解できます。
しかし(2)のキャストした後の値の変化の理由が分かりません。

朝日奈ありす さん
補数?を利用して足し算(実際には減算)している事は理解出来ました。

しかし、0xC7 (-57) が 0xFFFFFFC7 (-57)に変化している事が、もうひとつ理解出来ません。

申し訳御座いませんが、もう少し詳しく教えていただけませんでしょうか。



(Javaというよりパソコンの基礎知識かもしれませんね。)

よろしくお願いいたします。
未記入
大ベテラン
会議室デビュー日: 2005/03/12
投稿数: 148
投稿日時: 2007-10-20 11:27
Javaのbyteが符号ありだから(byte)0xC7は-57です。

int型の0x000000C7では199になってしまう。
値を変えてしまったらまずいでしょ。

/*
byteで表現できない値のintを
byteに変換したい場合は
値が変わってしまうのは仕方ないけど。
*/

int型の-57は0xFFFFFFC7なんだよ。

2の補数について調べるといいんじゃないかな。
負の値を補数で表現すると最上位ビットが1なら負の値を示す意味になる。
2の補数でたとえば-57+57は、4バイトなら16進数で示すと
0xFFFFFFC7+0x00000039=0x100000000となり答えを4バイトに制限すると
0になり-57+57=0となる。

[ メッセージ編集済み 編集者: 未記入 編集日時 2007-10-20 11:41 ]

読み返してみた。
2の補数ってことも判っているようだし
int型に変換されたことも判っているようだし
ただなんとなく脳内のそれらのつながりが弱くてしっくり来ないだけなのかな。

[ メッセージ編集済み 編集者: 未記入 編集日時 2007-10-20 11:49 ]
未記入
会議室デビュー日: 2007/10/20
投稿数: 3
投稿日時: 2007-10-20 12:15
未記入さん

回答ありがとうございます。

おかげさまで理解出来ました。

> ただなんとなく脳内のそれらのつながりが弱くてしっくり来ないだけなのかな。
その通りでした。
1

スキルアップ/キャリアアップ(JOB@IT)