调试器中的表达式显示正确的计算值,但在分配给变量时值被四舍五入
Expression in Debugger shows correct value of calculation, but value is rounded when assigning to variable
我使用 STM32 通过 I2C 逐字节读取 16 位二进制补码传感器数据,因此我必须将 High- 和 Low-Byte 重新组合在一起并将此数字转换为浮点数以获得实际值.
我在 C 中的表达是
// Convert temperature value (256 LSBs/°C with +25°C Offset)
float temp = (tmpData[1] << 8 | tmpData[0])/256.0 + 25.0;
当我使用 STM32CubeIDE 的调试器检查计算时,表达式显示数据的正确转换(见屏幕截图)。但是分配给 temp 变量的值始终是 25!在我看来,表达式的第一项总是假定为 0 或其他什么?我已经尝试将括号中的术语直接转换为浮动,但这并没有改变任何东西。
任何人都可以指出我的问题吗?为什么调试器显示正确的值,但代码分配了错误的值?
以下截图中的表达式是在调试模式下将鼠标悬停在上述代码行的相应部分上得到的。
图1:完整的计算表达式(给出结果符合预期)
图2:tmpData内容(原来两个Bytes)
图3:字节移位和粘贴的结果
图4:临时结果(始终为 25,即使上面的表达式显示预期值)
temp 目前只是一个 volatile,因为我还没有使用那个值,编译器会优化它。
这一行代码中有很多问题。
tmpData[1] << 8
必须是 (((uint16_t)tmpData[1]) << 8)
。如果将字节移位 8 次,结果将为零(标准表示未定义)。您可能收到了有关它的警告。
256.0 和 25.0 是 double
值,结果也将是 double
,然后转换为 float
。你应该使用 256.0f 和 25.0f.
你可以在这里看到区别:https://godbolt.org/z/Cm-S8T
好的,新的早晨,新的直觉……
问题不在于问题中的这一行代码,而在于(典型的 Murphy)我没有 post 的东西。 I2C 通过 DMA 读取到阵列,而在我想进行转换时,外围设备尚未完成。这就是为什么当代码访问数组元素时数组元素总是空的,但是当我检查调试器中的值时,I2C 外设已经完成传输并且我看到了预期值。
所以解决办法就是检查外设是否还在忙...
我使用 STM32 通过 I2C 逐字节读取 16 位二进制补码传感器数据,因此我必须将 High- 和 Low-Byte 重新组合在一起并将此数字转换为浮点数以获得实际值.
我在 C 中的表达是
// Convert temperature value (256 LSBs/°C with +25°C Offset)
float temp = (tmpData[1] << 8 | tmpData[0])/256.0 + 25.0;
当我使用 STM32CubeIDE 的调试器检查计算时,表达式显示数据的正确转换(见屏幕截图)。但是分配给 temp 变量的值始终是 25!在我看来,表达式的第一项总是假定为 0 或其他什么?我已经尝试将括号中的术语直接转换为浮动,但这并没有改变任何东西。
任何人都可以指出我的问题吗?为什么调试器显示正确的值,但代码分配了错误的值?
以下截图中的表达式是在调试模式下将鼠标悬停在上述代码行的相应部分上得到的。
图1:完整的计算表达式(给出结果符合预期)
图2:tmpData内容(原来两个Bytes)
图3:字节移位和粘贴的结果
图4:临时结果(始终为 25,即使上面的表达式显示预期值)
temp 目前只是一个 volatile,因为我还没有使用那个值,编译器会优化它。
这一行代码中有很多问题。
tmpData[1] << 8
必须是(((uint16_t)tmpData[1]) << 8)
。如果将字节移位 8 次,结果将为零(标准表示未定义)。您可能收到了有关它的警告。256.0 和 25.0 是
double
值,结果也将是double
,然后转换为float
。你应该使用 256.0f 和 25.0f.
你可以在这里看到区别:https://godbolt.org/z/Cm-S8T
好的,新的早晨,新的直觉……
问题不在于问题中的这一行代码,而在于(典型的 Murphy)我没有 post 的东西。 I2C 通过 DMA 读取到阵列,而在我想进行转换时,外围设备尚未完成。这就是为什么当代码访问数组元素时数组元素总是空的,但是当我检查调试器中的值时,I2C 外设已经完成传输并且我看到了预期值。
所以解决办法就是检查外设是否还在忙...