何时使用DBL_EPSILON / epsilon

时间:2010-06-24 12:34:44

标签: c++ c numeric numerical-analysis

DBL_EPSILON / std :: numeric_limits :: epsilon会给我一个最小的值,当添加一个时会有所不同。

我无法理解如何将这些知识应用到有用的东西中。

epsilon比计算机可以处理的最小值大得多,所以看起来正确的假设是使用比epsilon更小的值是安全的吗?

我正在使用的值之间的比率是否应小于1 / epsilon?

2 个答案:

答案 0 :(得分:4)

DBL_EPSILON的定义不是这样。它是1和1之后的下一个可表示数字之间的差异(您的定义假定舍入模式设置为“朝向0”或“朝向负无穷大”,这并非总是如此)。

如果你对数值分析有足够的了解,这是有用的。但是我担心这个地方不是最好的人。作为一个例子,你可以用它来构建一个比较函数,它可以判断两个浮点数是否近似相等,如下所示

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

(但不知道如何确定ulp,你就会丢失;如果中间结果是非正规数,这个函数可能会出现问题; fp计算很复杂,无法实现健壮)

答案 1 :(得分:1)

XX的下一个值之间的差异因X而异。
DBL_EPSILON只是11的下一个值之间的差异。

您可以使用std::nextafter来测试两个带有epsilon差异的double

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;
}

如果你想用因子* epsilon差异测试两个double,你可以使用:

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;
}