FLT_EPSILON в JavaScript, как мне перевести этот код?

Я перевожу некоторый код на C ++ относительно PMP для контроля ориентации и использования части кода FLT_EPSILON,

Код делает следующее:

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

M_PI это просто, но я не уверен, что с FLT_EPSILON, Гугл сказал мне:

Это разница между 1 и наименьшей плавающей точкой
число типа float больше 1. Предполагается, что нет
больше чем 1E-5.

Однако другие источники заявляют такие ценности, как 1.192092896e-07F,

Я не на 100% понимаю, почему он используется. Я подозреваю, что это связано с гранулярностью поплавка. Так что, если кто-то может прояснить, что он пытается делать в 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;
}

— редактировать —

Просто понял, что fmodf не определен. По-видимому, это функция lib и выполняет следующие действия:

Функция fmod () вычисляет остаток с плавающей точкой от деления
х за у. Возвращаемое значение: x — n * y, где n — частное от x /
у, округляется от нуля до целого числа.

0

Решение

Этот код пытается сохранить angle в интервале около нуля.

Тем не менее, управление углами таким образом является хлопотным и требует значительной осторожности. Если это не сопровождается документацией, объясняющей, что делается, почему, и различными ошибками и спецификациями, которые это делают, то это было сделано неправильно.

Для такого вида уменьшения угла невозможно точно сохранить накопленные изменения в течение длинной последовательности изменений, потому что M_PI является лишь приближением к π. Следовательно, такого рода сокращения обычно полезны только для эстетического или интерфейсного эффекта. Например, при изменении некоторого угла его уменьшение может удерживать его от роста до точки, в которой могут быть большие скачки в результатах вычислений из-за квантования с плавающей запятой или других ошибок вычислений, которые могут раздражать зрителя. Таким образом, поддерживая угол в пределах интервала около нуля, дисплей выглядит хорошо, даже если он отличается от того, что реальная физика сделала бы в долгосрочной перспективе.

Выбор FLT_EPSILON кажется произвольным. FLT_EPSILON важно для представления тонкости float формат. Однако по величине M_PIULP (самое прекрасное изменение) float на самом деле 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); может быть ошибка, так как это уменьшение по модулю M_PI скорее, чем 2*M_PI, поэтому он добавит 180 ° к некоторым углам, что приведет к совершенно неправильному результату.

Возможно, что замена всего тела функции на return fmod(angle, 2*M_PI); будет работать удовлетворительно.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]