我有一个应该包含按位计算结果的 uint8_t。调试器说变量设置正确,但是当我检查内存时,var 始终为 0。无论调试器告诉我什么,代码都像 var 一样继续运行为 0。这是代码:
temp = (path_table & (1 << current_bit)) >> current_bit;
//temp is always 0, debugger shows correct value
if (temp > 0) {
DS18B20_send_bit(pin, 0x01);
} else {
DS18B20_send_bit(pin, 0x00);
}
Temp 是一个 uint8_t
,path_table 是一个 uint64_t
,current_bit 是一个 uint8_t
。我试图让它们都变成 uint64_t 但没有任何改变。我也尝试过使用 unsigned long long int 代替。什么都没有。
代码总是进入 else 子句。 Chip 的 Atmega4809,在代码的其他部分使用 uint64_t 没有问题。
注意 - 如果有人知道从变量中提取单个位的更有效/更紧凑的方法,我将不胜感激 ^^
最佳答案
1
是一个整数常量,类型为 int
.表达式 1 << current_bit
也有类型 int
, 但对于 16 位 int
,当 current_bit
时,该表达式的结果未定义大于 14。在您的情况下行为未定义,那么您的调试器可能会显示与观察到的行为不一致的整体表达式的结果。如果您使用 unsigned int
相反,即 1u
,那么每当 current_bit
时,temp 的结果值将被很好地定义为 0大于 15,因为左移的结果将为零。
通过在足够宽的类型中执行计算以保存结果来解决此问题。下面是更正代码以执行此操作的紧凑、正确且非常清晰的方法:
DS18B20_send_bit(pin, (path_table & (((uint64_t) 1) << current_bit)) != 0);
或者如果path_table
有一个无符号类型,那么我更喜欢这个,尽管它与您的原始类型有很大不同:
DS18B20_send_bit(pin, (path_table >> current_bit) & 1);
关于c - AVR uint8_t 没有得到正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54887015/