如何确定双重的最小显着变化

cho*_*syg 7 floating-point

我有问题确定eps给定的双变量的最小值,v这样

v+eps != v
Run Code Online (Sandbox Code Playgroud)

请注意,这不是典型的问题表任务,因为它eps取决于任意数字v.

这不应该通过在for循环中寻找这个值来完成.有没有快速的方法来做到这一点,例如通过位移?独立于编译器,优化标志,平台......

谢谢你的回答

rub*_*nvb 3

C99 函数nextafter正是您所需要的。或者,使用 Boost.Math 的nextafter. double这是由定义定义的实现(它依赖于内存中的内部表示)。

要对撰写本文时答案中提供的所有方法进行比较,请参阅现场演示以了解其他解决方案如何失败。


作为参考,如果您想在我们自己的系统上运行它,这里是测试代码:

#include <cmath>
#include <cfloat>
#include <limits>
#include <iostream>
using std::cout;
#include <iomanip>
using std::setprecision;

#include <boost/math/special_functions/next.hpp>

double
epsFor( double x )
{
  union
  {
    double d;
    unsigned long long i;
  } tmp;
  tmp.d = x;
  ++ tmp.i;
  return tmp.d - x;
}

void test(double d)
{
  double d1 = std::nextafter(d,DBL_MAX);
  double d2 = d+std::numeric_limits<double>::epsilon() * d;
  double d3 = d+epsFor(d);
  double d4 = boost::math::nextafter(d, DBL_MAX);
  cout << setprecision(40)
       << "For value of d = " << d << '\n'
       << " std::nextafter: " << d1 << '\n'
       << " Boost solution: " << d4 << '\n'
       << " undefined beh.: " << d3 << '\n'
       << " numeric_limits: " << d2 << '\n';
}

int main()
{
  test(0.1);
  test(986546357654.354687);
}
Run Code Online (Sandbox Code Playgroud)