LoginSignup
2
1

More than 5 years have passed since last update.

組込みC > 0x89と0xAAの合成 > wrk = vals[0] << 8 | vals[1]; > 0xFFFF89AA > 計算途中が符号付き16ビット(short)になり、そこで負数になる + 符号拡張により先頭がFFFFになる

Last updated at Posted at 2018-03-13
動作環境
組込みC (16bit)
...
unsigned char vals[] = { 0x89, 0xAA };
unsigend long wrk;

wrk = vals[0] << 8 | vals[1]; // MSB + LSB

wrkの値が0xFFFF89AAとなる。左ビットがF埋めされる。

以下だとF埋めされなかった。

wrk = (unsigned long)vals[0] << 8 | vals[1];

以下でもF埋めされない。(unsigned long)がないとF埋めされる。

wrk = (unsigned long)vals[0];  // ここでいったんwrkに入れないと0xFFFF89AAのように上位側がFとなる
wrk = wrk << 8 | vals[1];

右シフト演算の場合、算術シフトにより符号ビットが付くというのは聞いたことがある。
シフト演算

そこで、右シフトをする時は空ビットは符号ビットで初期化されます

しかしながら、上記は左シフト演算である。

左シフト演算した値が、暗黙の型変換で「マイナス(かsigned型)」と認識して、F埋めされた状態になるのだろうか。

謝辞

@shiracamus さんのコメントにて動作の仕組みが理解できました。

情報感謝です。

@SaitoAtsushi さんのコメントにて仕様(C99)に関する情報を紹介いただきました。

情報感謝です。

@nakataSyunsuke さんにアイデアをいただき、そのコードを@SaitoAtsushi さんに実装いただきました。

情報感謝です。

2
1
13

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1