有人可以指向(或显示)C#中一些好的通用浮点比较函数来比较浮点值吗?我想实施的功能IsEqual,IsGreater一个IsLess。我也只在乎双打而不在乎浮动。
IsEqual
IsGreater
IsLess
编写有用的通用浮点IsEqual非常非常困难,即使不是完全不可能的。您当前的代码将因严重失败a==0。在这种情况下,该方法的行为确实是一个定义问题,并且可以说,最好针对特定领域用例量身定制代码。
a==0
对于这种事情,您 确实非常需要 一个好的测试套件。这就是我在《浮点指南》中所做的事情,这就是我最后想出的(Java代码,应该足够容易翻译):
public static boolean nearlyEqual(float a, float b, float epsilon) { final float absA = Math.abs(a); final float absB = Math.abs(b); final float diff = Math.abs(a - b); if (a == b) { // shortcut, handles infinities return true; } else if (a == 0 || b == 0 || absA + absB < Float.MIN_NORMAL) { // a or b is zero or both are extremely close to it // relative error is less meaningful here return diff < (epsilon * Float.MIN_NORMAL); } else { // use relative error return diff / (absA + absB) < epsilon; } }
您还可以在网站上找到测试套件。
附录: c#中相同的代码用于双打(按问题要求)
public static bool NearlyEqual(double a, double b, double epsilon) { const double MinNormal = 2.2250738585072014E-308d; double absA = Math.Abs(a); double absB = Math.Abs(b); double diff = Math.Abs(a - b); if (a.Equals(b)) { // shortcut, handles infinities return true; } else if (a == 0 || b == 0 || absA + absB < MinNormal) { // a or b is zero or both are extremely close to it // relative error is less meaningful here return diff < (epsilon * MinNormal); } else { // use relative error return diff / (absA + absB) < epsilon; } }