2011/08/17

[java]ビット演算

hiro99maさんからのお便りです。

こんにちは。
InListPassiveTargetでFeliCaのSystemCodeを取ってきたのですが、88b4がffb4になってしまいます。
なして?


なんでと言われてもねぇ。。。


private static short hl16(byte h8, byte l8) {
  return (short)(h8 << 8) | l8);
}

上位8bitになる変数を8bit左シフトして、下位8bitになる変数とORする。
そんだけだ。
さて、これでなぜだめなのだろうか?


ポイントは、引数がunsignedじゃないところ。
0x88も0xb4も、どちらもマイナス値として扱われてしまう。
-120と-76。

-120はビットシフトするので、0x8800。
これはいい。
問題は-76の方。

どうやら、Javaは演算時にintへ格上げするらしい。
原本を調べているのだが、記載が見つからん。。。

http://java.sun.com/docs/books/jls/second_edition/html/conversions.doc.html#27529

まあ、Cと同じルールと思っていていいんじゃないかな。
intになるのか、大きい方に合わせられるのかはわからんが、今回はどっちでもいい。
0xb4がshortになるのではなく、-76がshortになるのだ。
short型の-76を16進数にすると、0xffb4。
そう、上位8bitが0xffになってしまうのだ。
unsignedだったらこんなことはないのだけどね。。。

そんなわけで、下位8bitをshortに拡張した後で0xffとANDを取ればよい。

private static short hl16(byte h8, byte l8) {
  return (short)(((short)h8 << 8) | ((short)l8 & 0x00ff));
}





0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。