我只是为一个相当简单的物理模拟程序编写了一些代码,用户可以改变重力加速度,我想将最小重力值限制为某个值(以防止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()有用或者如何/何时使用它。
我刚才看到一些看起来像这样的代码:
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()进行了什么?
答案 0 :(得分:2)
从std::numeric_limits<T>::epsilon
上的info
,std::numeric_limits<T>::epsilon()
返回1 + std::numeric_limits<T>:epsilon()
不等于1的最小此类T.此值仅在std::numeric_limits<T>::is_integer()
时有用返回false。该值的名称是机器epsilon。
因为浮点数的表示在可表示的数字之间产生cppreference page,因为数字在数字线上离数字越来越远,因此epsilon()
的返回值需要缩放才能与结果。 Christer Ericson的实时碰撞检测描述了缩放背后的一些算法。他在书中建议的建议是,执行浮点等式检查时应该使用的epsilon值应该是机器epsilon的平方根。
Bruce Dawson的博客系列,我在上面链接,是学习浮点运算复杂性的重要资源。如果您想继续实施物理模拟,我强烈建议您阅读本系列中的所有帖子。