445 words
2 min
JavaのByteの計算で詰まった話
この記事は公開日から2年以上が経過しています。
入力されたbyteが0x00 ~ 0xFDの間にあるか確認したい
指定されたbyteが0x00 ~ 0xFDにいる事を確認したく以下コードを書いたとき
byte arg = (byte) 0x01;
if((byte) 0x00 >= arg && arg =< (byte) 0xFD){
System.out.println("問題なし");
}何故か条件に入らない、、、
Javaのbyteは符号付き
Javaのbyteは符号付きのためbyteを数値として表すと
-128 ~ 127
になる。
つまり、2進数の1000 0000で符号付きとして判断されるため
0x80 ~ 0xFFまではマイナスの値になる。
なので
(byte) 0x00 > (byte) 0xFFはtrueになる。
どうしたか
intとして扱ってあげれば符号付きで変換されないので
byte arg = (byte) 0x01;
if(0x00 >= arg && arg =< 0xFD){
System.out.println("問題なし");
}としてあげれば、やりたいことができる。
byte触る機会少なかったら気づかなかった…(言い訳)
補足:ビットマスク演算 (arg & 0xFF) を使った無符号化処理
また、別の解決策として & 0xFF によるビット演算を行い、int 型にプロモーションする方法も一般的です。
byte arg = (byte) 0xFD; // 数値としては -3
int unsignedArg = arg & 0xFF; // 0x000000FD (数値としては 253)
if (unsignedArg >= 0x00 && unsignedArg <= 0xFD) {
System.out.println("0x00〜0xFDの範囲内です");
}arg & 0xFF を行うことで、符号拡張によって1で埋まった上位24ビットがゼロクリアされ、0〜255の無符号整数(unsigned byteと同等)として安全に比較・計算が行えるようになります。
パケット解析やバイナリプロトコルを扱う処理では定番の書き方なので、あわせて押さえておくと安心です。