下林明正のブログ

個人的かつ雑多なブログです。

ビッグエンディアンとリトルエンディアンの狭間で

http://distilleryimage9.s3.amazonaws.com/b585a9d83b7811e2974722000a1fb774_7.jpg

Arduinoはリトルエンディアンな環境っぽい。

0xFF00 >> 8 == 255なのはなんとなく見た目通りだから良いけど、 65280 >> 8 == 255なのは違和感を感じる。なぜなら、65280はビッグエンディアンな環境なら0xFF00としてそのままメモリ上に表現されると思うけど、リトルエンディアンな環境ならメモリ上では0x00FFとして表現されていると思うから、8ビット右シフトしたら0になって欲しい気がする。

でも、実際にArduinoで動かしてみてSerial.printすると、そうはならない。

ここで0xFF00 == 65280とすると真が返っている。つまり、0xなんちゃらはビッグエンディアンっぽい表記をした後に内部的にリトルエンディアンに変換されていて、>>は右ビットシフトのつもりだったけどリトルエンディアンな環境だと実は左にビットシフトしているのかも知れない。

これまでビッグエンディアンな環境でしか作業をしてこなかったし、特に詳しく調べることもなかったのだけど、内部的なエンディアンとは別に記述は全部ビッグエンディアンっぽい感じにしよう、みたいな感じになっているのかも知れない。

ちなみに、実はArduinoがビッグエンディアンだった!というオチは無いっぽくて、バイト列を受け取ったAndroidは(というかJVMが?)ビッグエンディアンなのでリトルエンディアンをビッグエンディアンに変換して受け取っている。

こういうのってどこで調べれば良いんだろう。面倒そうなので調べる気が起きない。

long型のデータを頑張ってuint16_tの配列とかにぶつ切りにして突っ込んだりしていたらこういう疑問にぶち当たってわたわたしていた。

追記

以下のような意見をいただきました。

ビッグエンディアンっぽい方が便利、みたいな雰囲気です。

追記

そういえばC言語は"高級言語"だったことをじわじわ思い出してきた。