将float和double值与delta进行比较?

据我所知,必须仔细比较浮点类型的值,以避免固有浮点错误的问题。 这可以通过将值与错误阈值进行比较来改进。

例如,以下解决方案比简单的x == y测试更有用:

 static float CompareRelativeError(float x, float y) { return Math.Abs(x - y) / Math.Max(Math.Abs(x), Math.Abs(y)); } static bool CompareAlmostEqual(float x, float y, float delta) { return x == y || CompareRelativeError(x, y) < delta; } // apologies if this is a poor example if (CompareAlmostEqual(1f/10f, 0.1f)) { ... } 

上面的解决方案来自以下资源: 在Java中直接比较2 float / double时是否安全?

虽然我还没有找到任何文献来证实这一点,但对我来说似乎也必须适用于像x > y这样的比较。 例如,如果xy基本相等,那么一个如何大于另一个……

 static bool CompareGreater(float x, float y, float delta) { return x > y && !CompareAlmostEqual(x, y, delta); } 

因此以下对x >= y有效:

 static bool CompareGreaterOrEqual(float x, float y) { return x >= y; } 

我的假设是否正确?

等式测试正是delta(或epsilon)技术用于浮点值的原因。

例如,我们希望3等于2.999999 ……达到一定的精度。

所以当定义为: CompareGreaterOrEqual方法时,它是不够的:

 static bool CompareGreaterOrEqual(float x, float y) { return x >= y; } 

它应该是:

 static bool CompareGreaterOrEqual(float x, float y, float delta) { return x >= y || CompareAlmostEqual(x, y, delta); } 

注意:第一次测试中的x >= y可能只是x > y因为delta比较会处理相等:

 static bool CompareGreaterOrEqual(float x, float y, float delta) { return x > y || CompareAlmostEqual(x, y, delta); } 

由于我们已经同意operator =在这种情况下是通过CompareAlmostEqual完成的,因此在CompareGreaterOrEqual使用它也是有意义的。

 static bool CompareGreaterOrEqual(float x, float y, float delta) { return x >= y || CompareAlmostEqual(x, y, delta); } 

此外,虽然它在很大程度上取决于你如何利用这些函数,但我还要使delta成为整个类中使用的常量变量,以确保使用相同的值(而不是将其作为参数传递)。