【问题标题】:return value not as expected, MIN , compiler issue, numerical overflow?返回值与预期不符,MIN,编译器问题,数值溢出?
【发布时间】:2012-09-06 16:07:15
【问题描述】:

存在以下行代码(嵌入式编程、C 语言、Code Composer Studio 编译器):

bs[Line] = (21.0F - ( (13.5F / 0.035F) * (MIN( abs_yaw, 0.06F) - 0.025F) ) );

在哪里

#define MIN(a,b) (((a) < (b)) ? (a) : (b))

21.0F 是局部变量中的结果,

上一行中的其他值实际上是常量。

对于刚刚高于 0.025 的 abs_yaw(我们知道是这样),我们应该得到一个接近 abs 的 bs。 但是,我们得到的 bs 等于 -341.9...

任何想法为什么会发生这种情况?

【问题讨论】:

  • 请发布更多代码。具体来说,你实际为abs_yaw使用了什么值,bs[Line]是什么数据类型,比如float、double等
  • 可能性1:局部变量实际上不包含21.0f。可能性二:abs_yaw 不是变量,而是有副作用的表达式。可能性 3:您确实知道abs_yaw 刚好高于 0.025,实际上它更大。
  • @DanielFischer 确实,如果有更多代码,我们可以提供更好的帮助。
  • 我同意@DanielFischer,并补充说“错误”的值让我怀疑。它给出的不是大约 19-20 度(正确值),而是 -341.9,这是一个完整的圆减去相同的 19-20 度,就好像它是偏航校正出错了...... .

标签: c compiler-construction overflow min


【解决方案1】:

这段代码:

#include <stdio.h>

#define MIN(a,b) (((a) < (b)) ? (a) : (b))

int main(void)
{
    for (int i = 0; i < 20; i++)
    {
        float abs_yaw = 0.022 + (i / 4000.0);
        float result = (21.0F - ((13.5F / 0.035F) * (MIN(abs_yaw, 0.06F) - 0.025F)));
        printf("%2d: %6.4f yields %10.6f\n", i, abs_yaw, result);
    }
    return 0;
}

在 Mac OS X 10.7.4 上使用 GCC 4.7.1 生成这些结果。

 0: 0.0220 yields  22.157143
 1: 0.0223 yields  22.060715
 2: 0.0225 yields  21.964285
 3: 0.0227 yields  21.867857
 4: 0.0230 yields  21.771429
 5: 0.0233 yields  21.674999
 6: 0.0235 yields  21.578571
 7: 0.0237 yields  21.482143
 8: 0.0240 yields  21.385714
 9: 0.0243 yields  21.289286
10: 0.0245 yields  21.192858
11: 0.0247 yields  21.096428
12: 0.0250 yields  21.000000
13: 0.0253 yields  20.903572
14: 0.0255 yields  20.807142
15: 0.0258 yields  20.710714
16: 0.0260 yields  20.614286
17: 0.0262 yields  20.517859
18: 0.0265 yields  20.421429
19: 0.0268 yields  20.325001

您可以调整它以磨练您的价值观,但看起来应该没有问题,而且您可能发现了编译器错误。 OTOH,您的测试代码可能没有这么简单;如果你试试这个,它可能会起作用。所以,不要去声称编译器错误。假设您的代码中存在错误,直到所有其他方法都失败为止。尝试不同的编译器(就相同的代码获得第二意见)。

【讨论】:

  • 因为他是嵌入式编程,并且没有指定处理器类型或变量精度,据我们所知,它可能是在 16 位浮点数上捕获非规范化并刷新为 0,或替换定点数学。如果不可用,不同的编译器不一定能解决这个问题。 OP并没有真正指定。
  • 所有有效点,但这表示调试问题的方法。也可能没有printf(),也可能无法在嵌入式设备上显示。也许有一个模拟器。但是必须有很多证据才能让我相信问题出在编译器而不是代码中……这样的测试用例会有很大帮助。
  • @std''OrgnlDave 政治上不正确,但 OP 的名字表明它是她。
【解决方案2】:

任何想法为什么会发生这种情况?

是的:在您的代码中,您可以检查偏航角穿过一整圈以触发符号反转的情况,并且由于某些 other 错误(可能 0.025 是警卫)而执行该代码其他地方使用的边距?)。

结果,不是 20 度左右,而是 360°-20°,这就是 -341 值的来源。

当然,没有看到代码,这只是猜测。还有我自己过去错误的记忆。

【讨论】:

  • 如果这是一个赌博网站,我会投票赞成这个答案。但是 OP 中没有足够的信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
  • 2021-11-04
  • 1970-01-01
  • 2012-01-25
  • 2013-03-22
  • 2012-02-04
相关资源
最近更新 更多