2017-08-11 73 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是16位 - 而不是32位!這意味着除非另有說明,否則所有數字(包括整數常量)都被視爲int16_t

這意味着1 << 8(int16_t) 0x8000而不是(int32_t) 0x00008000,因爲它在32位平臺上。由於這是一個有符號值並且它的高位被設置,所以它是負值(具體地說,-32768),並且將其擴展到uint32_t給出0xffff8000

+0

非常感謝! –

0

你可以提供屏蔽值作爲一個無符號直接看到它如何影響行爲,這應該是預期:

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

1u << 150x8000u1 << 15作爲一個16位的值是-32767 。

+0

對不起!我做了一個編輯。我使用的分辨率實際上是15 –

+0

@JohnDoe:我更新了它。如果您希望1爲無符號,那麼將<< << 15符號轉換爲32位將會提供意想不到的結果。 – wallyk