比较两个花车

#include  bool Equality(double a, double b, double epsilon) { if (fabs(ab) < epsilon) return true; return false; } 

我试过这种方法比较两个双打,但我总是遇到问题,因为我不知道如何选择epsilon ,实际上我想比较小数字(小数点后6位数),如0.000001 。 我尝试了一些数字,有时我得到0.000001 != 0.000001 ,有时0.000001 == 0.000002除了与epsilon比较之外还有其他方法吗?

我的目的是比较两个双打(代表我的情况下的时间)。 表示以毫秒为单位的时间的变量t是double。 每次t改变时,它会增加另一个函数0.000001然后0.000002等。我想检查它是否等于double tt类型的另一个变量,如果tt == t,我有一些指令要执行..
谢谢你的帮助

看这里: http : //floating-point-gui.de/errors/comparison/

由于舍入错误,大多数浮点数最终略微不精确。 只要这种不精确性保持很小,通常就可以忽略它。 但是,它也意味着期望相等的数字(例如,当通过不同的正确方法计算相同的结果时)通常略有不同,并且简单的相等测试失败

当然, 每个计算机科学家应该知道浮点运算

第一:计算布尔值(使用<运算符)然后将其包装在另一个布尔值中是没有意义的。 就像这样写:

 bool Equality(float a, float b, float epsilon) { return fabs(a - b) < epsilon; } 

其次,你的epsilon本身可能没有很好地表现为float ,因此看起来不像你期望的那样。 尝试使用2的负幂,例如1/1048576。

或者,您可以比较两个整数。 只需将您的两个浮点数乘以所需的精度,然后将它们转换为整数。 务必正确地向上/向下舍入。 这是它的样子:

 BOOL floatcmp(float float1, float float2, unsigned int precision){ int int1, int2; if (float1 > 0) int1 = (int)(float1 * precision + .5); else int1 = (int)(float1 * precision - .5); if (float2 > 0) int2 = (int)(float2 * precision + .5); else int2 = (int)(float2 * precision - .5); return (int1 == int2); } 

请记住,当float a = +2^(254-127) * 1.___22 zeros___1并且float b = +2^(254-127) * 1.___23 zeros___然后我们期望abs(ab) < epsilon而是a - b = +2^(254-127-23) * 1.___23 zeros___ = 20282409603651670423947251286000这比epsilon大得多......

我编写并测试了这段代码。 看起来很有效。

 public static boolean equal(double a, double b) { final long fm = 0xFFFFFFFFFFFFFL; // fraction mask final long sm = 0x8000000000000000L; // sign mask final long cm = 0x8000000000000L; // most significant decimal bit mask long c = Double.doubleToLongBits(a), d = Double.doubleToLongBits(b); int ea = (int) (c >> 52 & 2047), eb = (int) (d >> 52 & 2047); if (ea == 2047 && (c & fm) != 0 || eb == 2047 && (d & fm) != 0) return false; // NaN if (c == d) return true; // identical - fast check if (ea == 0 && eb == 0) return true; // ±0 or subnormals if ((c & sm) != (d & sm)) return false; // different signs if (abs(ea - eb) > 1) return false; // b > 2*a or a > 2*b d <<= 12; c <<= 12; if (ea < eb) c = c >> 1 | sm; else if (ea > eb) d = d >> 1 | sm; c -= d; return c < 65536 && c > -65536; // don't use abs(), because: // There is a posibility c=0x8000000000000000 which cannot be converted to positive } public static boolean zero(double a) { return (Double.doubleToLongBits(a) >> 52 & 2047) < 3; } 
  • 如果任何数字是NaN,则数字不相等。
  • 如果2个数字相同,则相等。 这是一个快速的初步检查。
  • 如果两个数字都是+ 0,-0或次正规,则数字相等。
  • 如果数字有不同的符号,则数字不相等。 如果两个数字几乎为0(但不是±0或次正规)且具有不同的符号,则这看起来是错误的方法。 但是如果你把这些数字乘以另一个呢? 一个结果是负面的而另一个是积极的。 所以我们是严格的,这是对的。
  • 如果指数有2个或更多的差异,则数字不相等,因为一个数字至少是另一个数字的2倍。
  • 如果指数恰好为1,则从其中一个数字正确移位分数。
  • 如果2个分数的差异很小,则数字相等。