我知道,为了检查两个双数之间的相等性,您必须使用数字之间的绝对差并将此差与小于 1 且大于零的数字进行比较。这是最简单的方法,因为还有更复杂的方法。我的一位同事说,如果您将 Math.Round 用于 2 个小数位,则可以在不使用上述方法的情况下使用完全相等。因此,例如,如果您有数字
double x;
和数字double y;
,您可以只写
double x1=Math.Round(x,2);
double y1=Math.Round(y,2);
if(x1 == y1)
{
//do something
}
我不认为那是真的。 但是你能告诉我为什么这是对的还是错的?
不,因为四舍五入时,0.004999999 和 0.005000001 将不被视为相等(分别为 0.00 和 0.01),而 en epsylon 为 0.00002 时它们将相等。
参见C#的浮点比较函数。
您必须使用数字之间的绝对差值,并将此差值与小于 1 且大于零的数字进行比较。
不完全是。即使授予总是从较大的中减去较小的,根据该计划,
1.99
等于 1.01
,而 2.49
等于 1.51
。相反,将 1
替换为适合该情况的一些选定的 epsilon 值,并取比较的绝对值。 1.0
对于 epsilon 来说几乎总是太大了。像 0.000001
这样的东西可能更合适,但同样:你需要多精确取决于具体情况。
四舍五入和相等有什么关系
假设您想将
1/3
表示为小数。 你不能! 十进制值永远重复。相反,您必须满足于将值记录到一定位数。实际上,您已经对值进行了rounded。这是以 10 为基数的本质,事实证明以 2 为基数(二进制)也有同样的问题。事实上,0.1
与基数 2 的计算方式相同:你不能将它准确地存储 作为双精度值。
因此,您在浮点数空间中使用的许多值(其中 IEEE-754 是 far 最常见的,因为有直接的 CPU 支持和优化)实际上只是实际数字的 rounded 表示,并且当然这延伸到平等检查。
现在,比较两个双打的另一种策略是将它们四舍五入到相同的小数位数,然后比较四舍五入的值是否实际上相等,如问题的代码示例所示。 不推荐这样做。由于刚刚解释的浮点数的优化和不精确的性质,舍入后的值可能最终会成为略有不同的数字,并且仍然不会完全相等。