为什么这个简单的双断言在C#中失败

Rea*_*lar 3 c# floating-point floating-point-precision

以下测试将失败 C#

Assert.AreEqual<double>(10.0d, 16.1d - 6.1d);
Run Code Online (Sandbox Code Playgroud)

问题似乎是浮点错误.

16.1d - 6.1d == 10.000000000000002
Run Code Online (Sandbox Code Playgroud)

这使我在编写使用代码的单元测试时感到头痛double.有没有办法来解决这个问题?

And*_*bel 5

十进制系统和双精度的二进制表示之间没有精确的转换(请参阅下面的@PatriciaShanahan关于为什么的优秀评论).

在这种情况下,数字的.1部分是问题,它不能在双精度中有限地表示(如1/3不能有限地精确表示为十进制数).

一个代码片段,用于解释发生的情况:

double larger = 16.1d; //Assign closest double representation of 16.1.
double smaller = 6.1; //Assign closest double representation of 6.1.
double diff = larger - smaller; //Assign closest diff between larger and  
                                //smaller, but since a smaller value has a  
                                //larger precision the result will have better  
                                //precision than larger but worse than smaller. 
                                //The difference shows up as the ...000002.
Run Code Online (Sandbox Code Playgroud)

在比较双精度时,始终使用带参数的Assert.Equal重载delta.

或者,如果您确实需要精确的十进制转换,请使用decimal具有另一个二进制表示的数据类型,并且将10在您的示例中完全返回.

  • 稍微澄清一下:每个可以表示为二进制分数的值都具有完全相等的小数.那是因为两个是十分之一.该问题特定于从十进制到二进制的转换. (2认同)