C# bool值在调试模式下构建时与在发布模式下构建时不同

C# bool值在调试模式下构建时与在发布模式下构建时不同,c#,asp.net,C#,Asp.net,我在一个应用程序中有一个相当奇怪的bug,我已经设法缩小到这个简单的测试用例 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 h

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

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;
}
受保护的无效页面加载(对象发送方,事件参数e)
{
bool ISHEIGHTEXCENDED=ISHEIGHTEXCENDED(10.16f,127.15f);
lit.Text=ISHEIGHT.ToString();
}
超出专用边界(浮动y、浮动高度)
{
下一个浮动高度=y+高度;
返回(137.31f-下一个灯光)<0;
}
当我在调试模式下构建并运行它时,ISHEIGHTBOOL为False(正如我所期望的),但是当我在发布模式下重建并运行时,它现在为True

幕后发生了什么导致了这一点?我猜这和浮点精度有关,但不确定是什么


任何帮助都将不胜感激。

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


如果这是一个问题,这可能表明您不应该首先使用
浮点
双精度
——如果这些是精确值,请使用
十进制

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


如果这是一个问题,这可能意味着你不应该首先使用
浮点
双精度
——如果这些是精确的值,请使用
十进制

10.16+127.15正好等于137.31,这意味着
(137.31f-下右)
的理论值为0

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


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

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

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


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

尝试清理并重新生成解决方案?打印137.31f的结果-下一步并检查。与优化发布版本中的代码有关,优化计算结果,但是调试步骤可能无法做到这一点?试图清理并重新生成您的解决方案?打印137.31f-nextHeight的结果并进行检查。这与优化发布版本中的代码有关,优化了计算结果,但调试步骤无法做到这一点,也许吧?差别比单个.Epsilon的要大得多
137.31f-nextHeight
生成
-3814697265625e-06
,而
单个.Epsilon
1401298e-45
。在这里使用epsilon不会有什么帮助,尽管它通常是一个很好的建议。@DanielHilgarth我想的是一个“手工制作”的epsilon,而不是单一的epsilon。在我的生产代码中,我使用这些手工制作的ε,其值通常为1E-5或1E-6。我将编辑我的答案以避免混淆。区别远远大于
Single.Epsilon
137.31f-nextHeight
生成
-3814697265625e-06
,而
单个.Epsilon
1401298e-45
。在这里使用epsilon不会有什么帮助,尽管它通常是一个很好的建议。@DanielHilgarth我想的是一个“手工制作”的epsilon,而不是单一的epsilon。在我的生产代码中,我使用这些手工制作的ε,其值通常为1E-5或1E-6。我将编辑我的答案以避免混淆。谢谢,这很有意义,听起来可能是大小写-更改为小数确实会给出正确的结果。谢谢,这很有意义,听起来可能是大小写-更改为小数确实会给出正确的结果。