[英]Bit Shifting Error on Arduino
I am developing C++ libraries for the Arduino 2560 Mega and I have come across an interesting bug. 我正在为Arduino 2560 Mega开发C ++库,并且遇到了一个有趣的错误。
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)
It seems that in the first line, signed bits are padded onto the value before being assigned to the variable. 似乎在第一行中,将有符号位填充到值上,然后再分配给变量。 According to promotion rules I believe that the 1 should be cast to an unsigned integer. 根据升级规则,我认为应该将1强制转换为无符号整数。 But even then, I thought signed padding only occurs when you shift left. 但是即使那样,我认为带符号的填充仅在您向左移动时才会发生。
On the AVR architecture, an int
is 16 bits -- not 32! 在AVR架构上, int
是16位-而不是32位! This means that all numbers, including integer constants, are treated as a int16_t
unless otherwise specified. 这意味着,除非另有说明,否则所有数字(包括整数常量)都将被视为int16_t
。
This means that 1 << 8
is (int16_t) 0x8000
, not (int32_t) 0x00008000
as it would be on a 32-bit platform. 这意味着1 << 8
是(int16_t) 0x8000
,而不是(int32_t) 0x00008000
就像在32位平台上那样。 Since this is a signed value and it has its high bit set, it's negative (specifically, -32768), and sign-extending it to a uint32_t
gives 0xffff8000
. 由于这是一个有符号的值,并且已将其高位设置为1,因此它为负数(特别是-32768),并将其符号扩展为uint32_t
会得到0xffff8000
。
You could provide the mask value as an unsigned directly to see how that affects the behavior, which should be as expected.: 您可以直接将掩码值提供为无符号值,以查看其如何影响行为,这应该是预期的:
uint8_t resolution = 15;
uint32_t numDiscreteLevels = 1u << resolution;
1u << 15
is 0x8000u
whereas 1 << 15
as a 16-bit value is -32767. 1u << 15
是0x8000u
而1 << 15
作为16位值是-32767。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.