Pourquoi le biais de l’exposant IEEE-754 utilisé dans ce code C est 126.94269504 au lieu de 127?

La fonction C suivante est issue du projet 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; } 

Certains experts pourraient-ils expliquer ici pourquoi le biais de l’exposant utilisé dans le code ci-dessus est 126.94269504 au lieu de 127? Est-ce que la valeur de biais est plus précise?

Dans le projet que vous avez lié, ils ont inclus un cahier Mathematica avec une explication de leurs algorithmes, qui inclut la valeur “mystérieuse” -126.94269 .
Si vous avez besoin d’un lecteur, vous pouvez en obtenir un gratuitement sur le site Web de Mathematica .

Edit: Puisque je me sens généreux, voici la section pertinente sous forme de capture d’écran .

En termes simples, ils expliquent que la valeur est “plus simple, plus rapide et moins précise”.
Ils n’utilisent pas -126.94269 au lieu de -127 , ils l’utilisent à la place du résultat du calcul suivant (valeurs arrondies par souci de brièveté):

 -124.2255 - 1.498 * mx - (1.72588 / (0.35201 + mx)) 

Eh bien non, 126.94269504 n’est pas une valeur de biais “plus précise”. Ce code fait quelque chose de très, très étrange; Je suis assez surpris que cela fonctionne du tout. Il prend les bits d’un float comme s’il s’agissait d’un int (ce qui, selon mon expérience, vous donne généralement une valeur totalement erronée, mais peut-être pas), puis prend cette valeur “garbage” int et le reconvertit en un float, puis maths dessus. Comme on dit, c’est une façon rapide et approximative de faire quelque chose, dans ce cas, en prenant le log de base 2. Cela ne devrait pas fonctionner du tout, mais la différence entre 127 et 126.94269504 n’est manifestement qu’un des nombreux facteurs loufoques qui ont pour but de préserver le sens de ce qui devrait être un code dénué de sens. (Une sorte de “deux choses presque fausses font une quasi-bonne” chose.)

Si vous voulez extraire exactement la mantisse et l’exposant d’un float (bien que cela ne soit ni aussi rapide ni aussi approximatif), la méthode habituelle pour le faire consiste à frexpf fonction frexpf .