les nombres réels dans c [Xcode IDE]
J'ai commencé à apprendre le langage c, mais le problème est que je suis confus sur la façon d'utiliser les nombres réels. J'utilise Xcode IDE. Voici les résultats qui m'a permis de les confondre:
float x1 = 1.123456789123456789f;
double x2 = 1.123456789123456789f;
float x3 = 987654321.123456789f;
double x4 = 987654321.123456789f;
printf("x1 = %.20f\n", x1);
printf("x2 = %.20f\n", x2);
printf("x3 = %10.10f\n", x3);
printf("x4 = %10.10f\n", x4);
La sortie est:
x1 = 1.12345683574676513672 x2 = 1.12345683574676513672 x3 = 987654336.0000000000 x4 = 987654336.0000000000
La question est, pourquoi x1
, x2
perdre leur float chiffres après 1.12345678
? Et pourquoi x3
et x4
sont tronqués?
- Aussi, x3 et x4 produit mal nombres décimaux - 987654336 au lieu de 987654321
Vous devez vous connecter pour publier un commentaire.
Le problème fondamental est que les nombres à virgule flottante seulement ont une précision limitée: ils ne peuvent représenter que le nombre de chiffres significatifs avant de courir hors de l'espace. Il ne pas importe si ces chiffres avant le point décimal ou après lui, le nombre total de chiffres significatifs questions. Notez que ce problème est pas limité à C, il peut être vu dans toutes les langues/les environnements qui utilisent des nombres à virgule flottante.
double
devrait être en mesure de stocker deux fois plus de chiffres quefloat
, mais tous vos virgule flottante littéraux sontfloat
littéraux. Supprimer laf
postfix sur ladouble
lignes afin de les utiliser tous les bits disponibles pour undouble
.Ce qu'il vous manque, c'est que vous êtes de mettre chacun de vos numéros par 2 conversions de base, et x2 et x4 également par le biais d'un élargissement de conversion de type.
Tout d'abord, vous avez décimal littéraux, qui le compilateur convertit en binaire, les fractions de type
float
, qui ont une précision de 23 chiffres binaires (équivalent à environ 7.2 chiffres décimaux) et ne peut pas représenter fidèlement la plupart des fractions décimales, même ceux qui rentrent dans leur précision. Ensuite, x2 et x4 sont affectés àdouble
variables, mais vu que tout ce qui ne rentre pas dans les 23 chiffres binaires a déjà été coupées, elles ne sont pas comme par magie regagner la précision qui a été présent dans les littéraux.Ensuite, vous convertir le binaire fractions de retour à la virgule par
printf
, et d'obtenir la mention précédemment ca. 7.2 décimales correctes, et tout ce qui suit reflète la représentation de l'erreur d'arrondi créé par la base de conversion.C'est essentiellement le même que si vous essayez de convertir 1/3 à une fraction décimale 0.333 et à l'arrière pour une bonne fraction 333/1000 - hey, pourquoi n'est-il pas 1/3?
Lire la virgule flottante guide pour plus d'informations.
BigDecimal
par exemple, il y a probablement des bibliothèques à faire de même, C. Alternativement, vous pouvez stocker des montants monétaires en cents (ou la plus petite unité possible vous avez besoin) et les mettre en forme pour fonctionner correctement.BigDecimal
est à Base 10, à virgule flottante en précision arbitraire du système. Ces deux fait ensemble de le rendre mieux adapté pour les valeurs monétaires.