Почему искажение экспоненты IEEE-754, используемое в этом коде C, составляет 126,94269504 вместо 127?
Следующая функция C - это проект fastapprox.
static inline float
fasterlog2 (float x)
{
union { float f; uint32_t i; } vx = { x };
float y = vx.i;
y *= 1.1920928955078125e-7f;
return y - 126.94269504f;
}
Могут ли некоторые эксперты объяснить, почему погрешность экспоненты, используемая в приведенном выше коде, составляет 126.94269504 вместо 127? Это более точное значение смещения?
Ответы
Ответ 1
В проекте, который вы связали, они включали блокнот Mathematica с объяснением их алгоритмов, который включает в себя "таинственное" значение -126.94269
.
Если вам нужен зритель, вы можете бесплатно получить его на веб-сайте в форме скриншота.
Проще говоря, они объясняют, что значение "проще, быстрее и менее точно".
Они не используют -126.94269
вместо -127
, они используют его вместо результата следующего вычисления (значения округлены для краткости):
-124.2255 - 1.498 * mx - (1.72588 / (0.35201 + mx))
Ответ 2
Ну, нет, 126.94269504 не является "более точным" значением смещения. Этот код делает что-то очень, очень странное; Я очень удивлен, что он работает вообще. Он принимает бит float, как если бы они были int (что в моем опыте обычно дает вам абсолютно мусорное значение, но, может быть, и нет), затем принимает значение intb "мусора" и преобразует его обратно в float, а затем некоторые математика на нем. Это, как говорится, быстрый и приблизительный способ сделать что-то в этом случае, взяв бэк-бэг-2. Он не должен работать вообще, но разница между 127 и 126.94269504, по-видимому, является лишь одним из нескольких тупых факторов вымысла, которые предназначены для спасения некоторого значения от того, что должно быть бессмысленным кодом. (Сорт "два почти несправедливых дела делают почти правду".)
Если вы хотите извлечь именно мантиссу и экспоненту поплавка (хотя это не будет так быстро или приближенно), обычный способ сделать это с помощью функции frexpf
.