我正在翻译一些与PMP相关的c++代码,用于姿态控制,部分代码使用FLT_EPSILON。
该守则做了以下工作:
while (angle > ((float)M_PI+FLT_EPSILON))M_PI很简单,但我不知道如何使用FLT_EPSILON。谷歌告诉我:
这是类型浮点数的最小浮点数大于1的差值,它应该不大于1E-5。
但是,其他源会声明1.192092896e-07F之类的值。
我不完全清楚为什么要使用它。我怀疑这与浮子的高贵性有关。因此,如果有人能够澄清它试图在c++中做什么,如果这是javascript的问题,那么这将是非常有帮助的。
我不知道javascript如何在内部处理类似这些值的东西,所以我们会感谢您的帮助。
作为一个FYI,我正在翻译的代码如下(来自QGroundControl,它是开源的):
float limitAngleToPMPIf(float angle) {
if (angle > -20*M_PI && angle < 20 * M_PI) {
while (angle > ((float)M_PI + FLT_EPSILON)) {
angle -= 2.0f * (float)M_PI;
}
while (angle <= -((float)M_PI + FLT_EPSILON)) {
angle += 2.0f * (float)M_PI;
}
} else {
// Approximate
angle = fmodf(angle, (float)M_PI);
}
return angle;
}编辑
刚刚意识到fmodf还没有定义。显然,它是一个lib函数,并执行以下操作:
fmod()函数计算x除以y的浮点余数,返回值为x* y,其中n是x/y的商,向零四舍五入为整数。
发布于 2013-06-08 02:17:57
此代码试图将angle保持在零左右的间隔内。
然而,以这种方式管理角度是很麻烦的,需要相当小心。如果没有说明正在做什么,为什么,以及所涉及的各种错误和规范的文档,那么它是不正确的。
这种角度缩减不可能在长时间的变化序列中保持精确的累积变化,因为M_PI只是π的一个近似。因此,这种缩减通常只对美学或界面效果有用。例如,由于一些角度的变化,减少它可以阻止它增长到一个点,在计算结果可能会有很大的跳跃,因为浮点量化或其他计算错误,将是烦人的观众。因此,保持角度在零附近的间隔,使显示看起来很好,尽管它偏离了真正的物理将做的长期。
FLT_EPSILON的选择似乎是任意的。FLT_EPSILON对于表示float格式的精细性是很重要的。然而,在M_PI的大小上,float的ULP (最好的变化)实际上是2*FLT_EPSILON。此外,JavaScript用双精度算法执行加法,FLT_EPSILON在这种double格式中没有特别的意义。我怀疑作者选择FLT_EPSILON只是因为它是一个方便的“小”数字。我希望这些代码的工作效果与angle > M_PI编写时一样好,没有任何点缀,而且无论出现什么地方,(float) M_PI都被更改为M_PI。( FLT_EPSILON的添加可能是为了给系统添加一些滞后,这样它就不会频繁地在π附近的值和接近-π的值之间切换。然而,我建议的标准,angle > M_PI,也包括一些相同的效果,尽管数量较少。对于那些缺乏浮点运算经验的人来说,这一点可能并不明显。)
而且,看起来angle = fmodf(angle, (float) M_PI);可能是一个bug,因为它减少了模M_PI而不是2*M_PI,所以它会在某些角度增加180°,从而产生一个完全不正确的结果。
用return fmod(angle, 2*M_PI);替换整个功能体是可能的。
https://stackoverflow.com/questions/16995129
复制相似问题