内置在调试模式下的bool值与发布模式下的bool值不同

时间:2012-08-07 10:24:39

标签: c# asp.net

我在应用程序中有一个相当奇怪的错误,我已经设法缩小到这个简单的测试用例。

protected void Page_Load(object sender, EventArgs e)
{
    bool isHeightExceeded = IsHeightExceeded(10.16f, 127.15f);
    lit.Text = isHeightExceeded.ToString();
}

private bool IsHeightExceeded(float y, float height)
{
    float nextHeight = y + height;
    return (137.31f - nextHeight) < 0;
}

当我在调试模式下构建并运行它时,isHeightExceeded bool为False(正如我所料)但是当我在发布模式下重建并运行时它现在为True。

幕后发生了什么导致这种情况?我猜它与浮点精度有关,但不完全确定是什么。

任何帮助都将不胜感激。

2 个答案:

答案 0 :(得分:4)

我怀疑10.16f + 127.15f的值是以64(或80)位计算的,然后与137.31f进行比较...而在释放模式下计算该值,然后截断为32位且然后比较。基本上,当中间值没有被限制到较小的精度时,你可以得到这样的结果。

如果这是一个问题,可能建议您不要使用floatdouble开头 - 如果这些是精确值,请使用{ {1}}而不是。

答案 1 :(得分:1)

10.16 + 127.15恰好等于137.31,这意味着(137.31f - nextHeight)的理论值为0。

由于涉及数值运算,因此可能会导致数值精度问题。使用调试器时,可能会以不同方式处理此问题。这只是一个猜想,但我不会感到惊讶。

在任何情况下,您的代码都需要更正以解决精度错误,并使用自定义 epsilon 容差值(例如,0.00001)以便为人类提供可预测的结果读者和用户。如果您不添加此容差,则代码可能仅适用于双值,而不适用于阅读它的人。