Duplicaté possible: strong>
Exemples d'inacciciation à virgule flottante P>xxx pré> résultat: 0.299999999999999999889 P>
xxx pré> résultat: 15.000000000000014211 p>
donc. "A 'est plus petit que cela devrait être. Mais si nous prenons "A" 50 fois - le résultat sera plus grand qu'il ne devrait l'être. P>
Pourquoi est-ce? Et comment obtenir le résultat correct dans ce cas? P> blockquote>
5 Réponses :
Les ordinateurs stockent des nombres de points flottants en binaires, pas décimales. P>
De nombreux chiffres qui semblent ordinaires en décimale, tels que 0.3, n'ont aucune représentation exacte de la longueur finie en binaire. Si vous ajoutez de nombreux nombres à virgule flottante, ces minuscules différences s'additionnent et vous obtenez des résultats inattendus. P>
Par conséquent, le compilateur choisit le nombre le plus proche qui a une représentation binaire exacte, tout comme vous écrivez 0.33333 code> pour
1/3 code>. P>.
Je pense que la réponse clé pour l'OP est: "Vous ne pouvez pas obtenir le résultat correct en utilisant un point flottant". :)
Vous obtenez le résultat correct. Montre-paintement, pas le résultat que vous attendiez.
Ce n'est pas que c'est plus grand ou plus petit, c'est juste qu'il est physiquement impossible de stocker "0,3" comme valeur exacte à l'intérieur d'un numéro de point flottant binaire. P>
Le moyen d'obtenir le résultat "correct" est de ne pas afficher 20 décimales. P>
Pour obtenir le résultat "correct", essayez p>
Liste des bibliothèques arithmétiques arbitraires de précision de Wikipedia: http://fr.wikipedia.org/wiki/arbittrary-precision P >
ou p>
L'arithmétique décimale et arbitraire de précision est très probablement inutile pour les objectifs de l'OP.
Pour obtenir les résultats corrects, ne définissez pas la précision supérieure à celle disponible pour ce type numérique: Bien que si cette boucle fonctionne pendant 5 000 itérations au lieu de 50, l'erreur accumulée montrera Même avec cette approche - c'est à quel point le nombre de points flottants fonctionne. p> p>
+1 pour numeric_limits ne suffisent pas assez connu comme ils devraient l'être.
Étant donné que les nombres à virgule flottante sont stockés en binaire, dans lequel 0,31001100110011001 ... répétant que 1/3 est 0.333333 ... se répète en décimal. Lorsque vous écrivez Gardez à l'esprit que pour les applications pour lesquelles le point flottant est conçu, ce n'est pas un problème que vous ne pouvez pas représenter 0,3 exactement. Le point flottant a été conçu pour être utilisé avec: p>
pour quelles conversions décimales binaires sont à peu près pertinentes par rapport à d'autres sources d'erreur. P>
Maintenant, si vous écrivez un logiciel financier, pour lequel 0,30 $ signifie exactement em> 0,30 $, c'est différent. Il existe des classes arithmétiques décimales conçues pour cette situation. P>
et comment obtenir un résultat correct dans ce cas? strong> p>
Limiter la précision à 15 chiffres significatifs est généralement suffisant pour masquer les chiffres "bruit". Sauf si vous avez réellement besoin em> une réponse exacte, c'est généralement la meilleure approche. P> 0.3 code>, vous obtenez réellement 0.9999999999999999888897769753748434595763683319091796875 (la représentation binaire infinie arrondie à 53 chiffres significatifs). P>
Peut-être que vous pourriez ajouter à la fin de votre premier paragraphe: "... car la série infinie de la représentation binaire de 0,3 est coupée à un moment donné, car les valeurs infinies ne peuvent pas être stockées sur un ordinateur".
Va lire à ce sujet. Les problèmes de point flottant ont besoin d'une étude minutieuse afin de ne pas faire d'erreurs dangereuses.
Avoir des valeurs exactes, utilisez des entiers à la place (ou de Bignum Lib) const int acc = 100; int TMP, A = 30 / ACC, B = 0; pour (char i = 1; i <= 50; i ++) b = b + a; STD :: COUT << INT (B / ACC) << "."; TMP = B% ACC; Si (TMP <10) std :: COUT << "0"; STD :: COUT << INT (TMP); Pour accélérer les choses, vous pouvez utiliser une puissance de 2 pour ACC SO *, /,% convertit à <<, >>, et