When to use DBL_EPSILON/epsilon

扶醉桌前 提交于 2019-12-05 13:37:52
AProgrammer

The definition of DBL_EPSILON isn't that. It is the difference between the next representable number after 1 and 1 (your definition assumes that the rounding mode is set to "toward 0" or "toward minus infinity", that's not always true).

It's something useful if you know enough about numerical analysis. But I fear this place is not the best one to learn about that. As an example, you could use it in building a comparison function which would tell if two floating point numbers are approximatively equal like this

bool approximatively_equal(double x, double y, int ulp)
{
   return fabs(x-y) <= ulp*DBL_EPSILON*max(fabs(x), fabs(y));
}

(but without knowing how to determine ulp, you'll be lost; and this function has probably problems if intermediate results are denormals; fp computation is complicated to make robust)

The difference between X and the next value of X varies according to X.
DBL_EPSILON is only the difference between 1 and the next value of 1.

You can use std::nextafter for testing two double with epsilon difference:

bool nearly_equal(double a, double b)
{
  return std::nextafter(a, std::numeric_limits<double>::lowest()) <= b
&& std::nextafter(a, std::numeric_limits<double>::max()) >= b;
}

If you would like to test two double with factor * epsilon difference, you can use:

bool nearly_equal(double a, double b, int factor /* a factor of epsilon */)
{
  double min_a = a - (a - std::nextafter(a, std::numeric_limits<double>::lowest())) * factor;
  double max_a = a + (std::nextafter(a, std::numeric_limits<double>::max()) - a) * factor;

  return min_a <= b && max_a >= b;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!