物理和标准::<double>numeric_limits::epsilon()...我们何时以及为什么需要它?

Physics and std::numeric_limits<double>::epsilon()...When and why do we need it?

本文关键字:何时 我们 为什么 limits lt 标准 double gt numeric epsilon      更新时间:2023-10-16

我只是为一个相当简单的物理仿真程序编写一些代码,用户可以改变重力加速度,我想将最小重力值限制为某个值(以防止0和负重性。)。

我最终得到了这样的事情:

if(g_accel > 0.1) {
    g_accel -= 0.1;
}

在程序开始时,g_accel设置为1.0。但是,它仍然允许用户在0.1以下到1.38778e-016之类的值。我对问题的解决方案是检查:

if(g_accel > 0.1+std::numeric_limits<double>::epsilon()) {
    g_accel -= 0.1;
}

除了使用魔术常数外,我的问题是我不知道为什么这是必要的,而且,我真的不明白为什么Epsilon()有用或使用它是如何/何时使用的。p>我也在看一些看起来像这样的代码:

inline void Vector2D::Normalize()
{ 
  double vector_length = this->Length();
  if (vector_length > std::numeric_limits<double>::epsilon())
  {
    this->x /= vector_length;
    this->y /= vector_length;
  }
}

std :: numeric_limits :: epsilon()?

是怎么回事

std::numeric_limits<T>::epsilon上的cppReference页面上, std::numeric_limits<T>::epsilon()返回最小的t,即 1 + std::numeric_limits<T>:epsilon()不等于1。仅当 std::numeric_limits<T>::is_integer()返回false时,此值才有用。该值的名称是机器Epsilon。

由于浮点数的表示形式会导致代表数字之间的差距更大,因为数字远离数字行的0,因此需要将epsilon()的返回值缩放以与结果合作。Christer Ericson的实时碰撞检测描述了缩放背后的一些数学。他在书中提出的建议是,执行浮点相等检查时应使用的Epsilon值应该是机器Epsilon的平方根。

布鲁斯·道森(Bruce Dawson)的博客系列是我上面链接的,是了解浮点算术的复杂性的重要资源。我强烈建议您阅读该系列中的所有帖子,如果您想继续实施物理模拟。