C++ 物理和标准::数值限制<;双重>;::epsilon()…何时以及为什么我们需要它?
我只是在为一个相当简单的物理模拟程序编写一些代码,用户可以改变重力加速度,我想将最小重力值限制在某个值(以防止0和负重力) 我的结局是这样的:C++ 物理和标准::数值限制<;双重>;::epsilon()…何时以及为什么我们需要它?,c++,floating-point,C++,Floating Point,我只是在为一个相当简单的物理模拟程序编写一些代码,用户可以改变重力加速度,我想将最小重力值限制在某个值(以防止0和负重力) 我的结局是这样的: if(g_accel > 0.1) { g_accel -= 0.1; } inline void Vector2D::Normalize() { double vector_length = this->Length(); if (vector_length > std::numeric_limits<do
if(g_accel > 0.1) {
g_accel -= 0.1;
}
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;
}
}
其中,g_accel在程序开始时设置为1.0。但是,它仍然允许用户将0.1降至1.38778e-016之类的值。我的解决方案是检查:
if(g_accel > 0.1+std::numeric_limits<double>::epsilon()) {
g_accel -= 0.1;
}
if(g\u accel>0.1+std::numeric\u limits::epsilon()){
g_加速度-=0.1;
}
除了使用魔法常数,我的问题是我不知道为什么这是必要的,而且,我真的不明白为什么epsilon()有用,或者如何/何时使用它
我刚才还在看一些代码,看起来像这样:
if(g_accel > 0.1) {
g_accel -= 0.1;
}
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;
}
}
inline void Vector2D::Normalize()
{
双向量长度=此->长度();
如果(向量长度>标准::数值限制::ε()
{
这->x/=向量长度;
这->y/=向量长度;
}
}
std::numeric_limits::epsilon()怎么了?在std::numeric_limits::epsilon
上,std::numeric_limits::epsilon()
返回1+std::numeric_limits:epsilon()
不等于1的最小T。只有当std::numeric\u limits::is\u integer()
返回false时,此值才有用。该值的名称为机器ε
由于浮点数的表示会导致可表示数字之间的差异,因为数字在数字行上离0越远,epsilon()
的返回值需要缩放才能与结果一起工作。克里斯特·埃里克森(Christer Ericson)的实时碰撞检测描述了缩放背后的一些数学原理。他在书中提出的建议是,执行浮点相等性检查时应使用的ε值应为机器ε的平方根
布鲁斯·道森(Bruce Dawson)的博客系列,我在上面链接了它,它是学习浮点运算复杂性的一个很好的资源。如果您想继续实现物理模拟,我强烈建议您阅读本系列的所有文章。对于浮点类型,您可以尝试在有限的位中存储无限个小数。这是不可能的,因此我们得到舍入误差,其中一个值应该是
1.0
,而可能是0.999998674
或其他值。另请参见,例如,和应有帮助。