Le code
float x = 3.141592653589793238;
double z = 3.141592653589793238;
printf("x=%f\n", x);
printf("z=%f\n", z);
printf("x=%20.18f\n", x);
printf("z=%20.18f\n", z);
vous donnera la sortie
x=3.141593
z=3.141593
x=3.141592741012573242
z=3.141592653589793116
où, sur la troisième ligne de la sortie, 741012573242
est garbage et sur la quatrième ligne, 116
est garbage. Les doubles ont-ils toujours 16 chiffres significatifs tandis que les flotteurs ont toujours 7 chiffres significatifs? Pourquoi les doubles n'ont-ils pas 14 chiffres significatifs?
Les nombres à virgule flottante en C utilisent le codage IEEE 754 .
Ce type d'encodage utilise un signe, un significande et un exposant.
En raison de cet encodage, de nombreux changements auront de petites modifications pour leur permettre d'être stockés.
En outre, le nombre de chiffres significatifs peut légèrement changer puisqu'il s'agit d'une représentation binaire et non décimale.
La précision simple (float) vous donne 23 bits de significand, 8 bits d'exposant et 1 bit de signe.
La double précision (double) vous donne 52 bits de significande, 11 bits d'exposant et 1 bit de signe.
Les doubles ont-ils toujours 16 chiffres significatifs tandis que les flotteurs ont toujours 7 chiffres significatifs?
Non, les doubles ont toujours 53 bits et les flottants ont toujours 24 bits (sauf pour les valeurs dénormales, les valeurs infinies et les valeurs NaN, mais elles font l’objet d’une question différente). Ce sont des formats binaires, et vous ne pouvez parler clairement que de la précision de leurs représentations en termes de chiffres binaires (bits).
Ceci est analogue à la question de savoir combien de chiffres peuvent être stockés dans un entier binaire: un entier non signé de 32 bits peut stocker des entiers allant jusqu'à 32 bits, ce qui ne correspond pas exactement à un nombre décimal de chiffres: tous les entiers allant jusqu'à Vous pouvez enregistrer 9 chiffres décimaux, mais vous pouvez également enregistrer un grand nombre de chiffres à 10 chiffres.
Pourquoi les doubles n'ont-ils pas 14 chiffres significatifs?
Le codage d'un double utilise 64 bits (1 bit pour le signe, 11 bits pour l'exposant, 52 bits de poids explicite et un bit implicite), ce qui correspond à double le nombre de bits utilisés pour représenter un float (32 bits).
float: 23 bits de signification, 8 bits d'exposant et 1 bit de signe.
( double: 52 bits de significande, 11 bits d'exposant et 1 bit de signe.
Il est généralement basé sur des chiffres significatifs de l'exposant et du significande en base 2, et non en base 10. D'après ce que je peux dire dans la norme C99, il n'y a pas de précision spécifiée pour les flottants et les doubles (autre que le fait que 1 et 1 + 1E-5
/1 + 1E-7
sont distinguables [float
et double
respectivement]). Cependant, le nombre de chiffres significatifs est laissé à l'utilisateur (ainsi que la base utilisée en interne, autrement dit, une implémentation pourrait décider de la baser sur une précision de 18 chiffres en base 3). [1]
Si vous devez connaître ces valeurs, les constantes FLT_RADIX
et FLT_MANT_Dig
(et DBL_MANT_Dig
/LDBL_MANT_Dig
) sont définies dans float.h.
La raison pour laquelle on l'appelle double
est que le nombre d'octets utilisés pour le stocker est le double du nombre d'un float (mais cela inclut à la fois l'exposant et le significande). Le standard IEEE 754 (utilisé par la plupart des compilateurs) alloue relativement plus de bits pour le significande que pour l’exposant (23 à 9 pour float
par rapport à 52 à 12 pour double
), raison pour laquelle la précision est plus grande. que doublé.
1: Section 5.2.4.2.2 ( http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf )
Un float a 23 bits de précision et un double en a 52.
Ce n'est pas exactement une double précision à cause de la façon dont IEEE 754 , et parce que binaire ne traduit pas vraiment bien en décimal. Jetez un coup d'oeil à la norme si cela vous intéresse.