在 Arduino 中转换 signed/unsigned int 变量的问题
Problem with converting signed/unsigned int variables in Arduino
我正在制作一个电路,它将从 4011 移位寄存器中提取数据。到目前为止它工作正常,但是当我的数字超过某个值时,奇怪的事情开始发生。
此代码将循环我所有的 4011。
typedef unsigned long u_long;
for (u_long i = 0; i < 32; i++)
{
digitalWrite(CLOCK_in,0);
delayMicroseconds(0.2);
bool bit = digitalRead(DATA_in);
Serial.print(bit,BIN);
if (bit) out |= (1 << i);
digitalWrite(CLOCK_in,1);
}
Serial.println((u_long)out);
Serial.println((u_long)out,BIN);
从第一个 "print()" 我得到:
00000000000000010000000000000000
这是我所期望的,因为这是我的输入(我的目标是将其转换为无符号长十进制 - 最高数字为 32 位)。从下一个 print()
开始,我得到 4294934528
。我认为这是不正确的。从最后一个 print()
函数,天真的我期望得到与第一个相同的答案,我得到 11111111111111111000000000000000
我漏掉的地方在哪里? bitshift 部分有问题吗?
我在没有 MCVE 的情况下立即发现了一个问题
for (u_long i = 0; i < 32; i++)
{
...
if (bit) out |= (1 << i);
...
}
在 Arduino 中 int
是 16 位类型,整数文字是 int
type by default. Shifting by more than the bit width invokes undefined behavior,因此当 i > 15
时,您的代码有 UB
要修复该问题,请使用 L
后缀使其成为 long
文字
if (bit) out |= (1L << i);
但是没有理由在 Arduino 中使用慢速 32 位变量进行循环。只需使用 int
,甚至更好 uint8_t
。还可以将 uint32_t
与输出类型的标准 UINT32_C
宏一起使用,这样您就不需要计算出正确的后缀
uint32_t out;
for (int i = 0; i < 32; i++)
{
...
if (bit) out |= UINT32_C(1) << i;
...
}
也就是说,您还需要提供 MCVE
我正在制作一个电路,它将从 4011 移位寄存器中提取数据。到目前为止它工作正常,但是当我的数字超过某个值时,奇怪的事情开始发生。
此代码将循环我所有的 4011。
typedef unsigned long u_long;
for (u_long i = 0; i < 32; i++)
{
digitalWrite(CLOCK_in,0);
delayMicroseconds(0.2);
bool bit = digitalRead(DATA_in);
Serial.print(bit,BIN);
if (bit) out |= (1 << i);
digitalWrite(CLOCK_in,1);
}
Serial.println((u_long)out);
Serial.println((u_long)out,BIN);
从第一个 "print()" 我得到:
00000000000000010000000000000000
这是我所期望的,因为这是我的输入(我的目标是将其转换为无符号长十进制 - 最高数字为 32 位)。从下一个 print()
开始,我得到 4294934528
。我认为这是不正确的。从最后一个 print()
函数,天真的我期望得到与第一个相同的答案,我得到 11111111111111111000000000000000
我漏掉的地方在哪里? bitshift 部分有问题吗?
我在没有 MCVE 的情况下立即发现了一个问题
for (u_long i = 0; i < 32; i++)
{
...
if (bit) out |= (1 << i);
...
}
在 Arduino 中 int
是 16 位类型,整数文字是 int
type by default. Shifting by more than the bit width invokes undefined behavior,因此当 i > 15
要修复该问题,请使用 L
后缀使其成为 long
文字
if (bit) out |= (1L << i);
但是没有理由在 Arduino 中使用慢速 32 位变量进行循环。只需使用 int
,甚至更好 uint8_t
。还可以将 uint32_t
与输出类型的标准 UINT32_C
宏一起使用,这样您就不需要计算出正确的后缀
uint32_t out;
for (int i = 0; i < 32; i++)
{
...
if (bit) out |= UINT32_C(1) << i;
...
}
也就是说,您还需要提供 MCVE