代码检查:浮点数的相等比较
使用 ==/!= 运算符比较浮点数通常不是一个好主意。 浮点值本质上是不精确的,比较它们的精确相等几乎从来不是期望的语义。 通过 ==/!= 运算符进行比较会检查浮点值的表示是否完全相同,如果涉及精度损失的任何算术运算,这种情况是非常不可能的。 例如,让我们执行两个简单的算术运算——
将
0.1加11次,以及将
0.1乘以11
——并检查它们的浮点结果是否相等:
double add = 0;
for (int i = 1; i <= 11; i++)
{
add += 0.1;
}
double multiply = 0.1 * 11;
Console.WriteLine(add == multiply); // false
在一次测试运行中,我们得到 add = 1.0999999999999999 和 multiply = 1.1000000000000001 (尽管不同的运行时可能会产生不同的结果),因此 == 运算符将比较结果评估为 false。
要正确地进行这种比较,我们需要指定一个容差,即一个值来指示结果可以偏离预期值的程度。 JetBrains Rider 帮助我们自动将比较重写为 Math.Abs([expression]) < [tolerance]。 容差 值取决于您执行的计算的精度。 在我们的示例中,我们可以安全地依赖于 0.000000001 的容差:
double add = 0;
for (int i = 1; i <= 11; i++)
{
add += 0.1;
}
double multiply = 0.1 * 11;
var tolerance = 0.000000001;
Console.WriteLine(Math.Abs(add - multiply) < tolerance); // true
请注意,此检查会忽略一些通常用作“标记值”的值,例如 0、 +无限、 -无限、 非数字 ,用于表示“尚未初始化的值”或“值缺失”,当通常期望非零值时。
然而,更好的方法是使用 double? 类型和 null 值。
最后修改日期: 2025年 9月 26日