10
votes

C ++ Point flottant précision

Duplicaté possible:

Exemples d'inacciciation à virgule flottante xxx

résultat: 0.299999999999999999889 xxx

résultat: 15.000000000000014211

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.

Pourquoi est-ce? Et comment obtenir le résultat correct dans ce cas?


2 commentaires

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


5 Réponses :


8
votes

Les ordinateurs stockent des nombres de points flottants en binaires, pas décimales.

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.
Par conséquent, le compilateur choisit le nombre le plus proche qui a une représentation binaire exacte, tout comme vous écrivez 0.33333 pour 1/3 . .

Si vous ajoutez de nombreux nombres à virgule flottante, ces minuscules différences s'additionnent et vous obtenez des résultats inattendus.


2 commentaires

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.



1
votes

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.

Le moyen d'obtenir le résultat "correct" est de ne pas afficher 20 décimales.


0 commentaires

-2
votes

Pour obtenir le résultat "correct", essayez

Liste des bibliothèques arithmétiques arbitraires de précision de Wikipedia: http://fr.wikipedia.org/wiki/arbittrary-precision

ou

http://speleorove.com/decimal


1 commentaires

L'arithmétique décimale et arbitraire de précision est très probablement inutile pour les objectifs de l'OP.



18
votes

Pour obtenir les résultats corrects, ne définissez pas la précision supérieure à celle disponible pour ce type numérique: xxx

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.


1 commentaires

+1 pour numeric_limits ne suffisent pas assez connu comme ils devraient l'être.



15
votes

pourquoi est-ce?

É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 0.3 , vous obtenez réellement 0.9999999999999999888897769753748434595763683319091796875 (la représentation binaire infinie arrondie à 53 chiffres significatifs).

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:

  • mesures physiques, qui sont souvent mesurées à seulement 4 figues SIG et jamais à plus de 15.
  • fonctions transcendantaux telles que les logarithmes et les fonctions de Trig, qui ne sont approchées que de toute façon.

    pour quelles conversions décimales binaires sont à peu près pertinentes par rapport à d'autres sources d'erreur.

    Maintenant, si vous écrivez un logiciel financier, pour lequel 0,30 $ signifie exactement 0,30 $, c'est différent. Il existe des classes arithmétiques décimales conçues pour cette situation.

    et comment obtenir un résultat correct dans ce cas?

    Limiter la précision à 15 chiffres significatifs est généralement suffisant pour masquer les chiffres "bruit". Sauf si vous avez réellement besoin une réponse exacte, c'est généralement la meilleure approche.


1 commentaires

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".