我已经阅读了很多有关浮动误差,浮动逼近的知识。
问题是:我从未读过有关现实世界问题的答案。今天,我遇到了一个现实世界的问题。这真的很糟糕,我真的不知道该如何逃脱。
看一下这个例子:
[TestMethod]
public void TestMethod1()
{
float t1 = 8460.32F;
float t2 = 5990;
var x = t1 - t2;
var y = F(x);
Assert.AreEqual(x, y);
}
float F(float x)
{
if (x <= 2470.32F) { return x; }
else { return -x; }
}
x
应该是2470.32
。但实际上,由于舍入错误,其值为2470.32031
。大多数时候,这不是问题。功能是连续的,一切都很好,结果差一点点。
但是在这里,我们有一个不连续的函数,而且误差确实很大。测试恰好在不连续点上失败。
如何使用不连续的函数处理舍入错误?
最佳答案
这里的关键问题是:
在某些情况下,当输入值发生很小的变化时,该函数的输出值就会发生较大(且显着)的变化。
您将错误的输入值传递给该函数。
如您所写,“由于舍入错误,[x的值]为2470.32031”。假设您可以编写所需的任何代码-简单地描述要执行的功能,并且一组专业的程序员将在几秒钟内提供完整的,无错误的源代码。你会告诉他们什么?
您提出的问题是,“我将为此函数传递一个错误的值2470.32031。我希望它知道正确的值是其他东西,并为我没有通过的正确值(而不是我通过的错误值)提供结果。”
通常,该问题无法解决,因为无法区分何时将2470.32031传递给该函数,而是将2470.32和2470.32031传递给该函数以及将2470.32031传递给该函数。您不能指望计算机能读懂您的想法。当您传递不正确的输入时,您将无法期望正确的输出。
这告诉我们,函数F内部没有解决方案。因此,我们必须缩小范围并研究更大的问题。您必须检查传递给F的值是否可以改进(以更好的方式或以更高的精度或使用补充信息来计算),或者问题的本质是否是当传递2470.32031时总是打算使用2470.32,以便这些知识可以合并到F中。