Que signifie cet idiome C?

Dupliquer possible:
Racine carrée rapide inverse inhabituelle de John Carmack (Quake III)

J’ai récemment découvert ce morceau de code sur un blog – il provient du moteur Quake3. Il est censé calculer rapidement la racine carrée inverse en utilisant la méthode de Newton-Rhapson.

float InvSqrt (float x){ float xhalf = 0.5f*x; int i = *(int*)&x; i = 0x5f3759df - (i>>1); x = *(float*)&i; x = x*(1.5f - xhalf*x*x); return x; } 

Quelle est la raison de faire int i = *(int*)&x; ? Faire int i = (int) x; au lieu de cela donne un résultat complètement différent.

int i = *(int*)&x; ne convertit pas x en un entier – il récupère les bits réels du float x , qui est généralement représenté par une valeur de 4 octets supplémentaire par rapport à ce que vous attendez.

Pour référence, cela est une très mauvaise idée si vous ne savez pas exactement comment les valeurs flottantes sont représentées en mémoire.

int i = *(int*)&x; dit “prenez les quatre octets qui constituent la valeur float x, et traitez-les comme s’il s’agissait d’un int.” les valeurs float et int sont stockées en utilisant des méthodes complètement différentes (par exemple, int 4 et float 4.0 ont des modèles de bits complètement différents)

Le nombre qui se termine dans i est la valeur binary de la représentation à virgule flottante IEEE du nombre dans x. Le lien explique à quoi ça ressemble. Ce n’est pas un langage courant en C, c’est un truc astucieux avant que les instructions SSE ne soient ajoutées aux processeurs x86 disponibles dans le commerce.