据我所知,必须仔细比较浮点类型的值,以避免出现固有浮点错误的问题。这可以通过将值与错误阈值进行比较来改进。
例如,以下解决方案比简单的 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)) { ... }
上述解决方案源自以下资源: Is it safe when compare 2 float/double directly in Java?
虽然我无法找到任何文献来证实这一点,但对我来说,这似乎同样适用于像 x > y
这样的比较。例如,如果 x
和 y
本质上相等,那么一个怎么会比另一个大...
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
,因为增量比较处理相等性:
static bool CompareGreaterOrEqual(float x, float y, float delta) {
return x > y || CompareAlmostEqual(x, y, delta);
}
关于c# - 将 float 和 double 值与 delta 进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14844659/