2017-08-11 14 views
0

私はArduino 2560 MegaのC++ライブラリを開発しています。興味深いバグを発見しました。Arduinoのビットシフトエラー

uint8_t resolution = 15; 

uint32_t numDiscreteLevels = (1 << resolution); //yields a value of 0xFFFF8000 

uint32_t numDiscreteLevels = ((uint32_t)1 << resolution); //yields 0x8000 (correct value) 

最初の行では、符号付きビットが変数に代入される前に値にパディングされているようです。プロモーションルールによると、私は1が符号なし整数にキャストされるべきだと考えます。しかし、それでも、あなたは左にシフトするときにのみ、署名された詰め物が発生すると思った。

答えて

3

AVRアーキテクチャでは、intは32ビットではなく16ビットです。つまり、特に指定しない限り、整数定数を含むすべての数値はint16_tとして扱われます。

これは、1 << 8(int16_t) 0x8000であり、32ビットプラットフォームでは(int32_t) 0x00008000ではないことを意味します。これは符号付きの値であり、上位ビットが設定されているため負の値(-32768)で、uint32_tに符号拡張して0xffff8000となります。

+0

ありがとう! –

0

あなたはそれが予想通り:

uint8_t resolution = 15; 
uint32_t numDiscreteLevels = 1u << resolution; 

1u << 150x8000uある1 << 15は、16ビット値は、-32767であるように、一方でなければならない行動をどのように影響するかを見るために直接符号なしとしてマスク値を提供することができます。

+0

申し訳ありません。私は編集をしました。私が使っていた解像度は実際には15 –

+0

です@ジョンドー:私はそれを更新しました。 1 << 15が32ビットに変換された場合、1が符号なしになると予想される場合は予期しない結果になります。 – wallyk