précision "flottant" vs. précision "double"
le code
float x = 3.141592653589793238;
double z = 3.141592653589793238;
printf("x=%fn", x);
printf("z=%fn", z);
printf("x=%20.18fn", x);
printf("z=%20.18fn", z);
vous donnera la sortie
x=3.141593
z=3.141593
x=3.141592741012573242
z=3.141592653589793116
où sur la troisième ligne de sortie 741012573242
sont les ordures et sur la quatrième ligne 116
sont les ordures. Est-ce que les doubles ont toujours 16 chiffres significatifs alors que les flotteurs ont toujours 7 chiffres significatifs? Pourquoi les doubles n'ont-ils pas 14 chiffres significatifs?
6 réponses
des nombres à virgule Flottante en C utilisation IEEE 754 encoding.
ce type d'encodage utilise un signe, un significand, et un exposant.
à cause de cet encodage, de nombreux nombres auront de petits changements pour leur permettre d'être stockés.
de plus, le nombre de chiffres significatifs peut changer légèrement puisqu'il s'agit d'une représentation binaire, et non d'une décimale.
Simple précision (float) vous donne 23 bits de significande, 8 bits d'exposant, et 1 bit de signe.
Double précision (double) vous donne 52 bits de significand, 11 bits d'exposant, et 1 bit de signe.
Do doubles ont toujours 16 significative des chiffres flotte toujours 7 chiffres significatifs?
Pas de. Les Doubles ont toujours 53 bits et les flotteurs ont toujours 24 bits (sauf pour les valeurs denormales, infinies, et NaN, mais ceux-ci sont sujets à une question différente). Ce sont des formats binaires, et vous ne pouvez parler clairement de la précision de leur représentations en termes de chiffres binaires (bits).
c'est analogue à la question de combien de chiffres peuvent être stockés dans un entier binaire: un entier non signé de 32 bits peut stocker des entiers avec jusqu'à 32 bits, qui ne correspond pas précisément à un nombre de décimales: tous les entiers de jusqu'à 9 décimales peuvent être stockés, mais beaucoup de nombres de 10 chiffres peuvent être stockés aussi bien.
pourquoi ne pas doubler 14 chiffres significatifs?
le codage d'un double utilise 64 bits (1 bit pour le signe, 11 bits pour l'exposant, 52 bits significatifs explicites et un bit implicite), qui est double le nombre de bits utilisés pour représenter un flotteur (32 bits).
float : 23 bits de significande, 8 bits d'exposant, et 1 bit de signe.
double : 52 bits de significand, 11 bits d'exposant, et 1 bit de signe.
il est généralement basé sur des chiffres significatifs de l'exposant et de significand en base 2, pas de base 10. De ce que je peux dire dans la norme C99, cependant, il n'y a pas de précision spécifiée pour les flotteurs et les doubles (autre que le fait que 1 et 1 + 1E-5
/ 1 + 1E-7
sont distinguables [ float
et double
repsectiously]). Cependant, le nombre de chiffres significatifs est laissée à l'exécutant (ainsi que de base ils utilisent en interne, en d'autres mots, un mise en œuvre pourrait décider de le faire sur la base de 18 chiffres de précision à la base 3). [1]
si vous avez besoin de 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 il est appelé un double
est parce que le nombre d'octets utilisés pour le stocker est le double du nombre d'un flottant (mais cela inclut à la fois l'exposant et le significand). La norme IEEE 754 (utilisée par la plupart des compilateurs) attribuent relativement plus de bits pour le significand que l'exposant (23 à 9 pour float
vs. 52 à 12 pour double
), ce qui explique pourquoi la précision est plus que doublée.
1: section 5.2.4.2.2 ( http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf )