如何使 100.02f - 100 == 0.02f 在 C# 中为真?
看来是四舍五入的问题。我有 float[] 数组以及对该数组的一些操作。我需要为此功能编写单元测试,但考虑到这种舍入问题,将预期值与结果值进行比较并不是一项简单的任务。是否有任何解决方法可以测试数组上的数学运算?谢谢
It seems to be rounding problem. I have array of float[] and some operations over this array. I need to write unit tests for this functionality, but comparing expected values to the resulted values happened to be not a simple task taking into account this rounding issues. Is any workaround to test math operations over my array? Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
舍入问题是浮点计算的固有部分。也许使用小数数组 (
decimal[]
)?Rounding issues are an inherent part of floating-point calculations. Use an array of decimals (
decimal[]
), perhaps?在单元测试中使用浮点数或双精度数时,您的测试框架可能允许您考虑可接受的增量。例如,使用 NUnit,您可以编写
理解浮点数和双精度数对于某些事物本质上是不精确的,这是设计使然。它们表示以 2 为基数的数字。如果您需要精确的以 10 为基数表示,请使用适当的类型:
十进制
。When using floats or doubles in unit tests, your testing framework may allow you to account for an acceptable delta. Using NUnit, for example, you might write
Understand that floats and doubles are inherently imprecise for certain things, and that is by design. They represent numbers in base 2. If you need accurate base 10 representation, use the appropriate type for that:
decimal
.如果您编写了
1.1 - 0.1 == 1.0
,它仍然会返回 false。这是因为您正在处理二进制数字系统中的浮点数。您无法在二进制中准确地表示 0.1,就像您无法在基数 10 中准确地表示 1/3 一样。在 C#、Java、C++、C、JavaScript、Python 以及使用 IEEE 浮点的所有其他编程语言中都是如此。标准。
If you'd written
1.1 - 0.1 == 1.0
, it would still return false. It's because you're dealing with floating point numbers in a binary number system. You can't represent 0.1 in binary exactly any more than you can represent 1/3 exactly in base 10.This is true in C#, Java, C++, C, JavaScript, Python, and every other programming language that uses the IEEE floating point standard.
您应该使用“epsilon”值来检查(其中 epsilon 由您选择)
我不知道这是否已经在 c# 中实现,这是“技术”方法
显然 epsilon 值应该足够小。另外我建议编写一个扩展方法,以便使用时感觉更舒服
You should use an "epsilon" value to check against (where epsilon is chosen by you)
I don't know if this is already implemented in c#, this is the "technical" approach
Obviusly the epsilon value should be enough small. Also I suggest to write an extension method to feel more comfortable when using it
由于您正在编写单元测试,因此您可以轻松计算出确切的输出是什么。只需计算输出,然后使用“往返”格式打印它,然后将该字符串粘贴到单元测试中:
然后您将得到类似
Assert.AreEqual(100.02 - 100, 0.019999999999996)
或者,您可以获取单元测试的输出并将其转换为字符串,然后比较该字符串。然后你最终会得到类似的结果:
Since you're writing unit tests, you can easily just compute what the exact output will be. Simply compute the output, then print it using the "roundtrip" format, and then paste that string into your unit test:
Then you'll end up with something like
Assert.AreEqual(100.02 - 100, 0.019999999999996)
Alternately, you can take the output of your unit test and convert it to a string, and then compare the string. Then you'll end up with something like:
你不应该真正比较浮点数是否相等——你无法避免这种舍入错误。根据您的用例,如果您希望在像您这样的情况下舍入更直观,请使用小数,或者将浮点数之间的差异与选定的“可接受”误差值进行比较。
You shouldn't really compare floats for equality – you can't avoid this sort of rounding errors. Depending on your use case, either use decimals if you want rounding to be more intuitive in cases like yours, or compare the difference between the floats to a chosen "acceptable" error value.