Greg Hewgill e IllidanS4 dieron un vínculo con una excelente explicación matemática. Intentaré resumirlo aquí para aquellos que no quieran entrar demasiado en detalles.
Cualquier función matemática, con algunas excepciones, se puede representar mediante una suma polinomial:
y = f(x)
se puede transformar exactamente en:
y = a0 + a1*x + a2*(x^2) + a3*(x^3) + a4*(x^4) + ...
Donde a0, a1, a2, ... son constantes . El problema es que para muchas funciones, como raíz cuadrada, para el valor exacto, esta suma tiene un número infinito de miembros, no termina en algún x ^ n . Pero, si nos detenemos en algún x ^ n todavía tendríamos un resultado con cierta precisión.
Entonces, si tenemos:
y = 1/sqrt(x)
En este caso particular, decidieron descartar todos los miembros polinomiales por encima del segundo, probablemente debido a la velocidad de cálculo:
y = a0 + a1*x + [...discarded...]
Y ahora ha bajado la tarea de calcular a0 y a1 para que y tenga la menor diferencia con el valor exacto. Han calculado que los valores más adecuados son:
a0 = 0x5f375a86
a1 = -0.5
Entonces, cuando pones esto en la ecuación, obtienes:
y = 0x5f375a86 - 0.5*x
Que es lo mismo que la línea que ves en el código:
i = 0x5f375a86 - (i >> 1);
Editar: en realidad, aquí y = 0x5f375a86 - 0.5*x
no es lo mismo que i = 0x5f375a86 - (i >> 1);
ya que cambiar el flotador como entero no solo divide por dos sino que también divide el exponente por dos y causa algunos otros artefactos, pero aún así se reduce a calcular algunos coeficientes a0, a1, a2 ...
En este punto, han descubierto que la precisión de este resultado no es suficiente para el propósito. Así que, además, hicieron solo un paso de la iteración de Newton para mejorar la precisión del resultado:
x = x * (1.5f - xhalf * x * x)
Podrían haber hecho algunas iteraciones más en un ciclo, cada una mejorando el resultado, hasta que se alcance la precisión requerida. ¡Así es exactamente como funciona en CPU / FPU! Pero parece que solo una iteración fue suficiente, lo que también fue una bendición para la velocidad. CPU / FPU hace tantas iteraciones como sea necesario para alcanzar la precisión del número de punto flotante en el que se almacena el resultado y tiene un algoritmo más general que funciona para todos los casos.
Entonces, en resumen, lo que hicieron fue:
Use (casi) el mismo algoritmo que CPU / FPU, aproveche la mejora de las condiciones iniciales para el caso especial de 1 / sqrt (x) y no calcule todo el camino hasta la precisión a la que llegará la CPU / FPU, pero se detendrá antes, por lo tanto ganando velocidad de cálculo.