【发布时间】:2009-12-02 11:25:27
【问题描述】:
当然,永远不应该比较由相等计算得出的浮点值,但始终使用较小的容差,例如:
double value1 = ...
double value2 = ...
if (Math.Abs(value1 - value2) < tolerance * Math.Abs(value1))
{
... values are close enough
}
但是,如果我使用 Math.Round,我是否可以始终确保结果值是一致的,即以下 Assert 始终会成功,即使舍入的值是一个不能用 double 精确表示的值?
public static void TestRound(double value1, double value2, int decimals)
{
double roundedValue1 = Math.Round(value1, decimals);
double roundedValue2 = Math.Round(value2, decimals);
string format = "N" + decimals.ToString();
if (roundedValue1.ToString(format) == roundedValue2.ToString(format))
{
// They rounded to the same value, was the rounding exact?
Debug.Assert(roundedValue1 == roundedValue2);
}
}
如果不是请举个反例。
编辑
感谢astander 提供了一个由蛮力生成的反例,证明结果在一般情况下不是“一致的”。这个反例在四舍五入的结果中有 16 位有效数字 - 在按比例缩放时它也会以同样的方式失败:
double value1 = 10546080000034341D;
double value2 = 10546080000034257D;
int decimals = 0;
TestRound(value1, value2, decimals);
不过,我也对更数学的解释感兴趣。对任何可以执行以下任何操作的数学化程度更高的 Stackoverflowers 给予奖励:
找到一个反例,其中舍入结果的有效数字少于 16 个。
确定舍入结果将始终为此处定义的“一致”的值的范围(例如,舍入结果中有效位数小于 N 的所有值) .
提供生成反例的算法方法。
【问题讨论】:
-
Eric Lippert 写了很多关于浮点数的文章,它们可能会有所启发..blogs.msdn.com/ericlippert/archive/tags/…
标签: .net floating-point