我在应用程序中有一个相当奇怪的错误,我已经设法缩小到这个简单的测试用例。
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。
幕后发生了什么导致这种情况?我猜它与浮点精度有关,但不完全确定是什么。
任何帮助都将不胜感激。
答案 0 :(得分:4)
我怀疑10.16f + 127.15f的值是以64(或80)位计算的,然后与137.31f进行比较...而在释放模式下计算该值,然后截断为32位且然后比较。基本上,当中间值没有被限制到较小的精度时,你可以得到这样的结果。
如果这是一个问题,可能建议您不要使用float
或double
开头 - 如果这些是精确值,请使用{ {1}}而不是。
答案 1 :(得分:1)
10.16 + 127.15恰好等于137.31,这意味着(137.31f - nextHeight)
的理论值为0。
由于涉及数值运算,因此可能会导致数值精度问题。使用调试器时,可能会以不同方式处理此问题。这只是一个猜想,但我不会感到惊讶。
在任何情况下,您的代码都需要更正以解决精度错误,并使用自定义 epsilon 容差值(例如,0.00001)以便为人类提供可预测的结果读者和用户。如果您不添加此容差,则代码可能仅适用于双值,而不适用于阅读它的人。