调试器中的表达式显示正确的计算值,但分配给变量时值被四舍五入

Posted

技术标签:

【中文标题】调试器中的表达式显示正确的计算值,但分配给变量时值被四舍五入【英文标题】:Expression in Debugger shows correct value of calculation, but value is rounded when assigning to variable 【发布时间】:2020-08-28 02:09:35 【问题描述】:

我通过 I2C 和 STM32 逐字节读取 16 位二进制补码传感器数据,因此我必须将高字节和低字节重新粘在一起并将这个数字转换为浮点数以获得实际值。 我在 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,因为我还没有使用那个值,编译器会优化它。

【问题讨论】:

你的调试器不工作 - 或者它总是显示十进制值 尝试将优化级别更改为-O0或-Og。也许很简单,这段代码还没有执行 我已经将它设置为-Og,现在我更改为-O0 -> 没有区别。太奇怪了,它对你有用!我再次更新了问题中的图像以显示 temp 的详细信息。实际上二进制表示让我认为它将“float”显示为int ...?! 【参考方案1】:

这一行代码中有很多问题。

    tmpData[1] &lt;&lt; 8 必须是 (((uint16_t)tmpData[1]) &lt;&lt; 8)。如果将字节移位 8 次,结果将为零(标准表示未定义)。您可能收到了有关它的警告。

    256.0 和 25.0 是 double 值,结果也将是 double 然后转换为 float。你应该使用 256.0f 和 25.0f。

您可以在这里看到不同之处:https://godbolt.org/z/Cm-S8T

【讨论】:

我根据您的更正更改了代码,但这不会更改输出。尽管如此,我还是不能完全理解为什么调试器已经显示了正确的值。 这是不可能的。你如何检查temp 的值? tempData 值是多少? Yuo fo 没有提供所需的信息 我通过在调试模式下将鼠标悬停在变量或表达式上来检查值。我用更详细的信息更新了问题。 @jusaca 它对我来说很好用。单击表达式中的值并查看下面显示的内容。 (详细信息十六进制,obral,默认等) 我写了一个答案,因为我终于弄明白了...感谢您的帮助和提示,它对您来说很好用!让我想到问题可能出在代码的另一部分。【参考方案2】:

好的,新的早晨,新的直觉……

问题不在于问题中的此代码行,而是(典型的墨菲)与我没有发布的内容有关。 I2C 通过 DMA 读取到阵列中,而在我想要进行转换的时候,外围设备还没有完成。这就是为什么当代码访问它们时数组元素总是空的,但是当我检查调试器中的值时,I2C 外围设备已经完成了传输并且我看到了预期的值。

所以解决办法是检查外设是否还在忙...

【讨论】:

以上是关于调试器中的表达式显示正确的计算值,但分配给变量时值被四舍五入的主要内容,如果未能解决你的问题,请参考以下文章

解决 vs2012 调试时 鼠标放到变量上之后,无法显示 值 添加 监视时 显示 未能计算表达式的值

我无法在python中正确地将我想要的值分配给一个变量[重复]

如何从转义闭包中获取值并将其分配给变量并在表格视图中显示

在qt creator中调试时如何访问字符串变量的完整值?

将表示 SQL 查询的记录数(计数)的值分配给 C# 中的变量

将`input`的值分配给变量但在JS中返回空白