FLT_EPSILON在javascript我如何翻译这段代码

FLT_EPSILON in javascript how do I translate this code?

本文关键字:翻译 段代码 代码 何翻译 EPSILON javascript FLT      更新时间:2023-09-26

我正在翻译一些与姿态控制的PMP相关的c++代码,部分代码使用FLT_EPSILON

代码执行以下操作:

while (angle > ((float)M_PI+FLT_EPSILON))

M_PI是简单的,但我不确定什么与FLT_EPSILON。谷歌告诉我:

表示1和最小浮点数之间的差值float类型大于1的个数。应该是否定的

然而,其他来源的状态值,如1.192092896e-07F

我不是百分之百清楚为什么它被使用。我怀疑这与浮子的粒度有关。因此,如果有人能澄清它在c++中试图做什么,如果这是javascript的一个问题,那么这将是非常有帮助的。

我不知道javascript是如何处理内部的东西,像这些值,所以帮助会很感激。

作为一个参考,我正在翻译的代码如下(来自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;
}

—edit—

刚刚意识到fmodf没有定义。显然,它是一个lib函数,并执行以下操作:

fmod()函数计算除法的浮点余数返回值是x - n * y,其中n是x/的商Y,向零四舍五入为整数。

这段代码试图将angle保持在0附近的间隔内。

然而,以这种方式管理角度是麻烦的,需要相当小心。如果没有文档来解释做了什么,为什么做,以及所涉及的各种错误和规范,那么它就做得不正确。

由于M_PI只是π的近似值,这种角度的减小不可能在长变化序列中准确地保持累积变化。因此,这种减少通常只对美观或界面效果有用。例如,当某个角度发生变化时,减小它可以防止它增长到由于浮点量化或其他计算错误而导致计算结果出现大跳跃的程度,这将使观看者感到厌烦。因此,保持角度在零附近的间隔内会使显示看起来很好,即使它偏离了长期的实际物理效果。

FLT_EPSILON的选择似乎是任意的。FLT_EPSILON很重要,因为它表示float格式的精细性。然而,在M_PI的量级下,float的ULP(最小变化)实际上是2*FLT_EPSILON。此外,JavaScript用双精度算法执行加法,FLT_EPSILONdouble格式中没有特别的意义。我怀疑作者选择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);替换整个函数体可能会令人满意。