简体   繁体   English

Arduino上的位移错误

[英]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 << 150x8000u1 << 15作为16位值是-32767。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM