如何将浮点表示与不连续函数结合起来?

Cyr*_*don 3 .net c# floating-point floating-accuracy

我已经阅读了大量关于浮动错误和浮动近似的事情,以及所有这些.
问题是:我从未读过现实世界问题的答案.而今天,我遇到了一个现实世界的问题.这真的很糟糕,我真的不知道如何逃避.

看看这个例子:

    [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; }
    }
Run Code Online (Sandbox Code Playgroud)

x应该是2470.32.但实际上,由于舍入误差,其值为2470.32031.
大多数时候,这不是问题.功能是连续的,一切都很好,结果有点值.
但是在这里,我们有一个不连续的功能,错误真的很大.测试在不连续点上完全失败.

如何处理不连续函数的舍入误差?

Eri*_*hil 6

这里的关键问题是:

  • 在输入值发生微小变化的某些情况下,该函数的输出值会发生较大(且显着)的变化.
  • 您正在向函数传递不正确的输入值.

在你写的时候,"由于舍入误差,[x的值]是2470.32031".假设您可以编写任何您想要的代码 - 只需描述要执行的功能,专家程序员团队将在几秒钟内提供完整的,无错误的源代码.你会告诉他们什么?

你提出的问题是,"我要将错误的值2470.32031传递给此函数.我希望它知道正确的值是其他东西,并提供正确值的结果,我没有通过,而不是我传递的错误值."

一般来说,这个问题是不可能解决的,因为无法区分2470.32031何时传递给函数,但2470.32是从2470.32031传递给函数和2470.32031的.你不能指望一台电脑能读懂你的想法.传递错误输入时,您无法预期输出正确.

这告诉我们的是,函数F内部没有解决方案是可能的.因此,我们必须缩小并查看更大的问题.您必须检查传递给F的值是否可以改进(以更好的方式计算或以更高的精度计算或使用补充信息计算),或者问题的性质是否如此,当2470.32031通过时,总是打算2470.32,这样这种知识可以纳入F.