Dans le livre Le langage de programmation C de Dennis Ritchie, il est mentionné que “Un nombre flottant est généralement une quantité de 32 bits, avec au moins six chiffres significatifs et une magnitude généralement comprise entre environ 10 ^ -38 et 10 + 38.”
Comment est-ce possible puisque nous n’avons que 32 bits? La limite supérieure ne devrait-elle pas être 2 ^ 32? J’ai essayé d’imprimer un float en bouclant et en multipliant ce dernier par 10, 38 fois, ce qui correspond à la sortie 1000000069440617300000000000000000000000000. Il doit également garder une trace du signe, alors comment stocke-t-il tout cela dans seulement 32 bits?
Voir Format à virgule flottante simple précision pour plus de détails sur un C float
typique.
Gamme de magnitude pour float dans le langage de programmation c?
#include printf("float magnitude range %e to %e\n", FLT_MIN, FLT_MAX); // typical result // float magnitude range 1.175494e-38 to 3.402823e+38
Comment est-ce possible puisque nous n’avons que 32 bits?
Un float
typique ne stocke en effet que 2 32 valeurs différentes. Pourtant, ils ne sont pas répartis linéairement mais logarithmiquement en groupes linéaires.
2 23 valeurs différentes dans la plage [2 -126 à 2 -127 )
…
2 23 valeurs différentes dans la plage [0.5 à 1.0)
2 23 valeurs différentes dans l’intervalle [1.0 à 2.0)
2 23 valeurs différentes dans la plage [2.0 à 4.0)
…
2 23 valeurs différentes dans la plage [2 127 à 2 128 )
Et leurs contre-parties négatives.
Egalement +/- zéros, petits nombres sous-normaux, +/- infini et pas-un-nombre
Il doit également garder une trace du signe, alors comment stocke-t-il tout cela dans seulement 32 bits?
1 bit for sign 8 bits for the binary exponent 23 bits for the significant (with a MSBit usually implied as 1) -- 32 bits
Lors de l’impression d’un FLT_DIG, FLT_DECIMAL_DIG
float
, seuls environ 6 FLT_DIG, FLT_DECIMAL_DIG
( FLT_DIG, FLT_DECIMAL_DIG
) sont généralement importants.
printf("%.*e\n", FLT_DIG-1, FLT_TRUE_MIN); printf("%.*e\n", FLT_DIG-1, FLT_MIN); printf("%.*e\n", FLT_DIG-1, acos(-1)); printf("%.*e\n", FLT_DECIMAL_DIG - 1, nextafterf(FLT_MAX, 0.0)); printf("%.*e\n", FLT_DECIMAL_DIG - 1, FLT_MAX);
Sortie
1.40130e-45 // min sub-normal 1.17549e-38 // min normal 3.14159e+00 // pi 3.40282326e+38 // number before max 3.40282347e+38 // max