👻

ちゃんとEndianを考慮してbytesから数値に直そう

2022/01/05に公開

すっごい基本だけど、endian考慮するの忘れて少しハマったので反省メモ

基本

LittleEndian: 下位から保存. 0x1234があったら、 byte[]{0x32, 0x12}
BitEndian: 上位から保存. 0x1234 があったら byte[]{0x12, 0x34}

cpu系は殆どがLittleEndian.
network処理なんかで初期情報が需要な場合のデータストアはBigEndian.
WAVファイルはLittleEndian.

WAVのパーサをチョロっと書いてたらハマった.

変換例: bytes -> short

下記はだめな例.
Endianも考慮されておらず、内部の演算もintで実行されるので正負もきちんと変換できない.

public short convertBytesToShort(byte[] data, int startIndex)
{
    return (short)(data[startIndex] | data[startIndex] << 8);
}

下記は正しい例.
きちんと、BitConverterにまかせてToInt16してあげる.
BitConverterは同じEndian同士での変換を前提としているので、 LittleEndian(Data)=>LittleEndian(CPU) であれば変換不要.
LittleEndian(Data)=>BigEndian(CPU) であれば、事前にreverseする必要がある.

public short convertLittleEndianBytesToShort(byte[] data, int startIndex)
{
    byte[] target = BitConverter.IsLittleEndian ? data : new[] {data[startIndex+1], data[startIndex]};
    return BitConverter.ToInt16(target, startIndex);
}

Discussion