daisuke_nomura の日記

Android プログラマーな鉄道ファンのブログ

複数のバイトにまたがる数値を取り出す方法

ファイルや通信において、識別子やコマンドの次にボディ部分が何バイトあるのかを複数のバイトを使って表現しています。
1バイトでは0〜255までしか表現できないので当然です。

10進数で2,035,461は、1F 0F 05の3バイト

複数のバイトで表現された数値を取り出して+演算子で足すと間違った値になります。

1F + 0F + 05 = 51

正しい結果を取り出すために異なる方法が必要です。
まず最初に書いた方法が以下でした。

byte[] data= new byte[3] { 0x1F, 0x0F, 0x05 };
string f = Convert.ToString(data[0], 16);
string s = Convert.ToString(data[1], 16);
string t = Convert.ToString(data[2], 16);

if (s.Length < 2)
s = "0" + s;
if (t.Length < 2)
t = "0" + t;

string th = f + s + t;

int i = Int32.Parse(th, System.Globalization.NumberStyles.HexNumber);

バイト型配列の中身を取り出して文字列型にし、0が足りないところに0を入れ、その後連結しint型にしています。
どう見ても文系プログラマです。本当にありがとうございました。
問題なく動くのが不思議です。

その後、左シフトを用いて以下のようになりました。

byte[] data= new byte[3] { 0x1F, 0x0F, 0x05 };
int i = (data[0] << 16) + (data[1] << 8) + data[2];

とてもスッキリしていますし、読みやすいです。
左シフトで対象を8ビット又は16ビット分左にシフトさせています。例えば1を左に8ビットシフトさせると256になります。
それにより、1Fは2,031,616になり、0Fは3,840となります。
2,031,616 + 3,840 + 5 = 2,035,461となり、本来の結果が取り出せます。