Code

2010年9月11日星期六

About Epsilon

前几天去cs4213的lab,做了一个dotproduct的问题,然后跟cosine对比结果。我当时用了"==",对比结果老是不对然后问TA。他说要用epsilon,我不知道是什么,问了好几遍什么是epsilon。最后TA懒得跟我解释就说,你不能这样直接比较,会有error,然后我就用">"比较,最后终于弄对了。

今天突然想起那天他说的epsilon,然后查了一下。原来这是一个学computing都应该知道的东西(汗~~)。这个跟floating point 的precision有关系,下面是从msdn上摘下来的:

Output
The difference between 1 and the smallest value greater than 1
 for float objects is: 1.19209e-007
The difference between 1 and the smallest value greater than 1
 for double objects is: 2.22045e-016
The difference between 1 and the smallest value greater than 1
 for long double objects is: 2.22045e-016

这是machine representation for floating number的局限性。又查了一下,比如说0.1011用十进制是 1/2 + 1/8 + 1/16也就是0.6875。机器能够精确表示的浮点数只有像0.5, 0.25, 0.75, 0.625...和他们的linear combination。这样float是32位,double是64位,long double是128位,他们能表示的最小数就不一样了。

所以在比较浮点数的时候要计算误差,这个误差就叫做epsilon。误差在一定的范围内了,就可以看作是相等了。

从上面可以看出来,float type的误差是在0.0000001和0.0000002之间的。所以epsilon应该是大于0.0000001的,不然就有可能永远无法接近正确值。    这个也是从网上找来的:

#define EPSILON 0.0001  // Define your own tolerance
#define FLOAT_EQ(x,v) (((v - EPSILON) < x) && (x <( v + EPSILON)))
int main()
{
  float a = 2.501f;
  a *= 1.5134f;
  if (FLOAT_EQ(a, 3.7850)) cout << "Expected value" << endl;
  else cout << "Unexpected value" << endl;
}

总结就是,今后做floating point comparison要用epsilon。

1 条评论:

Erencie 说...

你居然连epsilon都不知道,鄙视之~~