我已经阅读了很多有关浮动误差,浮动逼近的知识。
问题是:我从未读过有关现实世界问题的答案。今天,我遇到了一个现实世界的问题。这真的很糟糕,我真的不知道该如何逃脱。

看一下这个例子:

    [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中。

08-16 08:15