Gamme de magnitude pour float dans le langage de programmation c?

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