Arduino代码:移动位似乎将数据类型从int更改为long
Arduino code: shifting bits seems to change data type from int to long
在我的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,并且由于数字开始时为负数,因此结果必须保持负数。
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 错误:隐式转换更改符号:'int'到'unsigned long'
- 对 '(const Y) (int&, std::mersenne_twister_engine<long unsigned int,
- 自动类型默认为 int 而不是 long
- 错误:'class std::unique_ptr<std::set<long unsigned int> >'没有名为 'size' 的成员
- "1L << count"是什么意思?如何使用超出"unsigned long long int? "范围的语句编号打印?
- Visual studio 2013 和 g++ 7.1 中将 int 和 long 类型相乘时的 c++ 差异行为
- 错误:调用'begin(long double [nPoints])'没有匹配函数;使用硬编码的 int 与整数变量初始化向量
- 只读位置'__result.std::_Rb_tree_const_iterator<_Tp>::operator*<long long int>()'分配错误
- C++ vector::size_type:有符号与无符号;int vs. long
- 错误:将"long int (*)[4]"分配给"long int [4][4]"时的类型不兼容
- 没有匹配函数来调用"std::basic_ofstream<char>::write(std::string*, long long unsigned int)"
- 函数参数可以是char*、long或int.可能吗
- unsigned int/signed int/long-long:无法解释的输出
- 如何在C++中将二进制文件上下文转换为 int/long 值
- <int> <long> 当它们的大小相同时,将矢量转换为矢量?
- " long unsigned typedef int long ullong; "是什么意思?
- 我如何使用3个重载函数(参数的差异是int, long, float)同时只要求一个输入项
- 使用非固定整数(int, long)而不是固定大小的整数(int64_t, int32_t)有什么优势吗?