Arduino代码:移动位似乎将数据类型从int更改为long

Arduino code: shifting bits seems to change data type from int to long

本文关键字:int long 数据类型 代码 移动 Arduino      更新时间:2023-10-16

在我的Arduino上,以下代码产生我不明白的输出:

void setup(){
  Serial.begin(9600);
  int a = 250;
  Serial.println(a, BIN);
  a = a << 8;
  Serial.println(a, BIN);
  a = a >> 8;
  Serial.println(a, BIN);

}
void loop(){}

输出为:

11111010
11111111111111111111101000000000
11111111111111111111111111111010

我确实理解第一行:前导零不会打印到串行终端。但是,在移动位后,a的数据类型似乎已从 int 更改为 long(打印 32 位)。预期的行为是位向左移动,并且 int 具有的 16 位中"移出"的位被简单地丢弃。将位移回不会再次将"32 位"变量转换为"16 位"。

移动 7 个或更少的位置不会显示此效果。

我可能应该说我没有使用Arduino IDE,而是 https://github.com/sudar/Arduino-Makefile 的Makefile。

这是怎么回事?我几乎希望这是"正常的",但我不明白。还是打印例程中的东西只是在输出中添加了 16 个"1"?

恩诺

除了其他答案外,整数可能以 16 位或 32 位存储,具体取决于您拥有的 arduino。

Arduino 中的函数打印数字在 /arduino-1.0.5/hardware/arduino/cores/arduino/Print 中定义.cpp

size_t Print::printNumber(unsigned long n, uint8_t base) {
  char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
  char *str = &buf[sizeof(buf) - 1];
  *str = '';
  // prevent crash if called with base == 1
  if (base < 2) base = 10;
  do {
    unsigned long m = n;
    n /= base;
    char c = m - base * n;
    *--str = c < 10 ? c + '0' : c + 'A' - 10;
  } while(n);
  return write(str);
}

所有其他函数都依赖于这个函数,所以是的,当你打印它时,你的 int 会被提升为无符号长整型,而不是当你移动它时。

但是,该库是正确的。通过向左移动 8 个位置,整数中的负位变为"1",因此当整数值提升为无符号长整型时,运行时会正确地用 16 个额外的"1"而不是"0"填充它。

如果您使用此类值不是作为数字而是包含一些标志,请使用无符号 int 而不是 int


ETA:为了完整起见,我将为第二次换档操作添加进一步的解释。

一旦你触摸 int 数字内的"负位",当你向右移动时,运行时会用"1"填充数字以保留其负值。向左移动 k 位置对应于将数字除以 2^k,并且由于数字开始时为负数,因此结果必须保持负数。

相关文章: