【发布时间】:2013-07-16 14:40:37
【问题描述】:
我已经阅读了大量有关浮动误差和浮动近似等所有内容。
问题是:我从未读过现实世界问题的答案。今天,我遇到了一个现实世界的问题。而且这真的很糟糕,我真的不知道如何逃脱。
看看这个例子:
[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。
大多数时候,这不是问题。功能是连续的,一切都很好,结果有点偏离。
但是在这里,我们有一个不连续的函数,而且误差非常非常大。测试恰好在不连续点上失败。
如何处理不连续函数的舍入误差?
【问题讨论】:
-
那么问题出在哪里?我可以想到四个潜在的问题:首先,常量 8460.32 将被转换为不具有该精确值的浮点数,因为该精确值不能表示为浮点数。其次,2470.32 也是如此。第三,两个浮点数的减法会导致另一个错误,第四,进行幅度比较的代码可能不正确。如果有的话,这四个问题中的哪一个是您的实际问题?
-
这个问题的答案可能有用也可能没用:stackoverflow.com/questions/3420009/…
-
@EricLippert 从 8460 左右的浮点数中减去 5990 左右的浮点数始终是精确的(“Sterbenz 引理”),但是对于不同的常数,减法可能会导致错误。
-
不要使用不连续函数?在阈值处取一些小区域,并在两个行为之间进行线性插值?这不会使浮点相等性测试通过,但会产生最小的错误。
-
我认为对于不连续函数和实用、有界精度、数字表示的问题,没有任何万能的解决方案。您能否提供更多关于不连续函数的原因以及评估它的上下文的背景信息?
标签: c# .net floating-point floating-accuracy