C#单元测试中Assert.AreEqual值相同却失败的问题求助
解决C#单元测试中Double值Assert.AreEqual看似相等却失败的问题
这种情况本质是浮点数的显示值和实际存储值不一致——你看到的是截断到15位的字符串,但两个double在二进制层面的细微差异没被显示出来,导致肉眼看起来一样,实际比较时不相等。就算加了delta没解决,大概率是delta设置不合理或者没找到真实差异。
第一步:先搞清楚两个值的真实差异
把预期值和实际值用更高精度的格式输出,比如在测试里加两行代码:
Console.WriteLine("Expected full value: {0:G17}", expectedValue); Console.WriteLine("Actual full value: {0:G17}", actualValue);
G17格式会输出double能表示的全部有效数字(15-17位),这时候你就能看到两个值的真实差异了——比如一个是-0.5622535302317491,另一个是-0.5622535302317489,肉眼看不到,但实际不相等。
第二步:调整Delta(容差)的大小
如果加了delta还是失败,说明你设置的容差太小,比如用了1e-15,但实际差异比这个大。要根据你的计算场景设置合理的容差:
- 如果是普通计算,用
1e-9或1e-10通常足够; - 如果是涉及多次迭代的科学计算,可能需要放大到
1e-6; - 示例代码(xUnit):
Assert.Equal(expectedValue, actualValue, precision: 12); // 指定比较前12位有效数字
- 示例代码(MSTest):
Assert.AreEqual(expectedValue, actualValue, 1e-9); // 容差设为1e-9
特殊情况排查
如果上面两步还没解决,要考虑:
- 是否是正负零的问题?比如一个是
-0.0,一个是0.0,显示都是0.0,但实际不相等; - 计算顺序是否不同?比如
(a + b) + c和a + (b + c)因为浮点数精度,结果可能有细微差异; - 是否应该用
decimal代替double?如果是财务、货币类计算,decimal的精度更可控,不会有这类问题。
内容的提问来源于stack exchange,提问作者Panduranga Javalageri
相关产品推荐
相关产品推荐

