Экспонента — это по определению log₂ числа, округлённый вниз. То есть, в нашем примере это 10=log₂(1280)≈10.3219. Мантисса — то, что осталось после округления, и для неё log₂(1 + m) ≈ m с небольшой ошибкой. Получается, что если взять эти 32 бита и прочитать их не как float, а как обычное целое число, то старшие биты дадут целую часть логарифма, а младшие — дробную. То есть целочисленное представление float — это уже почти log₂(x), умноженный на 2²³ и сдвинутый на константу. Вот такой логарифм бесплатно, без единой операции.
В памяти экспонента хранится со смещением +127 (чтобы не возиться с отрицательными), то есть для нашей 10 записано 137. Мантисса хранится без ведущей единицы — только дробная часть 0.25, растянутая на 23 бита: 0.25 × 2²³ = 2 097 152. Склеиваем: 137 × 2²³ + 2 097 152 = 1 151 336 448, или 0x44A00000. Это и есть «целочисленное прочтение» нашего float.
Из школы помним, что log(1/√x) = −½ · log(x). Поделить на −2 в целых числах — это сдвиг на один бит и вычитание. Константа 0x5f3759df — это как раз «сдвиг» логарифмической шкалы, упакованный в одно число. Потом биты снова читаются как float, и у вас в руках ответ с ошибкой 3%. Дальше по методу Ньютона снижаем ошибку до 0.17%.
А закомментированная строка — дополнительная итерация, которая снижает ошибку c "до ~0.17%" до "до ~0,0005%". Вторую итерацию закомментировали: для графики и так достаточно.
Позже Крис Ломонт перебором нашёл чуть лучшую константу 0x5f375a86, но выигрыш микроскопический. (С) Rauf Aliev
Сегодня немного гиковское. Наткнулся на интересный алгоритм вычисления 1/√x в 1999 в исходниках Quake III Arena. Особенно красиво "what the fuck?" напротив операции вычитания из 0x5f3759df и еще закомментированная строка.
Вообще операция 1/√x нужна в графике часто — чтобы нормализовать вектор (освещение, отражения, физика) нужно разделить его на длину, а длина — это корень. В то время (1999) sqrt и деление были дорогими операциями (сейчас уже нет), а эта функция делала то же самое в 3–4 раза быстрее. Но забавно КАК делала.
Фокус в устройстве float (число с плавающей точкой). Комп хранит числа (например, 1280) в двоичной научной записи, типа как 1.25*2¹⁰ 📷 1.25*1024=1280). Показатель степени (10) называется экспонентой, под него отведено 8 бит. Множитель перед степенью (1.25) — мантисса, под неё 23 бита. Экспонента говорит, какого порядка число, мантисса уточняет его внутри этого порядка.
Экспонента — это по определению log₂ числа, округлённый вниз. То есть, в нашем примере это 10=log₂(1280)≈10.3219. Мантисса
На пляже Омаха первыми из врачей высадилась штабная группа 61-го медицинского батальона. С пишмашинками, папками и бланками . Медицинское снаряжение пришлось собирать на месте.