如何在c#中使100.02f - 100 == 0.02f为真
本文关键字:02f 为真 中使 | 更新日期: 2023-09-27 18:10:22
似乎是舍入问题。我有一个float[]数组和对这个数组的一些操作。我需要为这个功能编写单元测试,但是考虑到这个舍入问题,比较期望值和结果值并不是一项简单的任务。是否有任何解决方法来测试我的数组上的数学运算?由于
舍入问题是浮点计算的固有部分。也许可以使用小数数组(decimal[]
) ?
100.02m - 100
在单元测试中使用浮点数或双精度时,您的测试框架可能允许您考虑可接受的增量。例如,使用NUnit,你可以写
double expected = 1d;
double delta = 0.0001d;
double actual = classUnderTest.Method();
Assert.AreEqual(expected, actual, delta);
理解浮点型和双精度型对于某些事情本质上是不精确的,这是设计上的。它们表示以2为基数的数字。如果您需要精确的十进制表示,请使用相应的类型:decimal
。
如果你写了1.1 - 0.1 == 1.0
,它仍然会返回false。这是因为你处理的是二进制数制中的浮点数。你不能精确地用二进制表示0.1,正如你不能精确地用十进制表示1/3。
在c#、Java、c++、C、JavaScript、Python和其他使用IEEE浮点标准的编程语言中都是如此。
您应该使用"epsilon"值来检查(其中epsilon由您选择)
if (yourvalue <= (0.02f + epsilon) && yourvalue >= (0.02f - epsilon))
// do what you want
我不知道这是否已经在c#中实现了,这是"技术"方法
显然ε值应该足够小。另外,我建议编写一个扩展方法,以便在使用它时感觉更舒适
由于您正在编写单元测试,因此您可以轻松地计算出确切的输出。只需计算输出,然后使用"roundtrip"格式打印它,然后将该字符串粘贴到单元测试中:
float output = Operation(array);
Console.WriteLine(output.ToString("r"));
最后会得到Assert.AreEqual(100.02 - 100, 0.019999999999996)
或者,您可以将单元测试的输出转换为字符串,然后比较字符串。然后你会得到这样的结果:
Assert.AreEqual((100.02 - 100).ToString("f"), "0.02");
你不应该比较浮点数是否相等——你无法避免这种舍入错误。根据您的使用情况,如果您希望在像您这样的情况下更直观地四舍五入,则可以使用小数,或者将浮点数之间的差异与选择的"可接受的"错误值进行比较。