Pourquoi Visual Studio 2008 me dire ,9-,8999999999999995 = 0.00000000000000055511151231257827?
-
12-09-2019 - |
Question
Quand je tape ceci dans le Visual Studio 2008 fenêtre immédiate:
? .9 - .8999999999999995
Il me donne ce que la réponse:
0.00000000000000055511151231257827
La documentation dit qu'un double a 15-16 chiffres de précision, mais il me donne un résultat avec 32 chiffres de précision. Où est tout ce que la précision supplémentaire vient?
La solution
sont seulement 15-16 chiffres dans la réponse. Tous ces zéros à gauche ne comptent pas. Le nombre est en fait plus comme 5,5511151231257827 × 10 -16 . La partie mantisse a 15-16 chiffres en elle. L'exposant (-16) permet de déplacer la virgule sur 16 par endroits, mais ne change pas le nombre de chiffres du nombre total.
Modifier
Après avoir obtenu quelques commentaires, je suis curieux maintenant sur ce qui se passe réellement. Je l'ai branché le numéro en question dans ce . Il a pris la liberté de l'arrondissement le dernier « 27 » dans « 30 », mais je ne pense pas que cela change les résultats.
Le convertisseur se décompose le nombre dans ses trois parties binaires:
Signe: 0 (positif)
Exponent: -51
Significand: 1.0100000000000000000000000000000000000000000000000000 (binaire pour 1,25 10 )
Donc, ce nombre est de 1,01 2 2 × -51 , ou 1,25 10 2 × -51 . Comme il n'y a que trois chiffres binaires significatifs étant stockés, qui suggéraient que Lars peut être sur quelque chose. Ils ne peuvent pas être « bruit aléatoire », car ils sont les mêmes à chaque fois que le nombre est converti.
Les données suggèrent que le seul chiffre enregistré est « 5 ». Les zéros proviennent de l'exposant et le reste des chiffres apparemment aléatoires sont de calcul 2 -51 .
Autres conseils
Vous devriez lire: Ce que tout informaticien doit- Savoir sur Virgule flottante Arithmétique .
Fondamentalement, il se résume à un nombre flottant point enregistré avec une précision finie. Vous devez faire votre comparaison avec un certain delta.
if(.9 - .8999999999999995 <= 0.0001)
//close enough to be equal
Les zéros ne sont pas significatifs / partie de la précision (jusqu'à la nombre à virgule flottante est concerné - mathématiquement parlant, ils sont significative). Les zéros sont dus à la partie exposant de la représentation interne du nombre à virgule flottante.
La partie 55511151231257827
(qui est le mantisse ou mantisse ) comporte 17 chiffres décimaux, ce qui est assez proche de 15-16 chiffres.
@Lars D: Qu'est-ce que vous considérez être correct, n'est correcte dans le contexte de la question. .9 - .8999999999999995
fonctionne à un flotteur avec significand 0,625 et exposant de -50. Prendre 0,625 * 2 -50 Résultats dans 5.5511151231257827e-16. Maintenant, hors du contexte de la question initiale, nous avons un certain nombre avec 17 chiffres significatifs qui ne arriver à être notre meilleure approximation binaire de ,0000000000000005. Cependant, ces zéros ne sont pas encore significatifs dans la mesure où la représentation du nombre à virgule flottante est concerné.
? ,9-,8999999999999995
Ce processus de soustraction, avec 15-16 chiffres significatifs, donne
,0000000000000005
Le reste des chiffres sont simplement des erreurs d'arrondi. Cependant, étant donné que l'ordinateur stocke toujours 15-16 chiffres significatifs après le premier chiffre non nul, les erreurs d'arrondi sont présentés, et vous obtenez beaucoup de chiffres aléatoires de fuite produites par des erreurs d'arrondi. Ainsi, le résultat a 16 chiffres significatifs de l'opération de soustraction plus 16 chiffres à partir du stockage du résultat, ce qui donne 32 chiffres.
Le « flottant » une partie de « virgule flottante » signifie que vous obtenez quelque chose de plus proche de 5,5511151231257827 * 10 ^ (- 16). Ce n'est pas exactement comment il est représenté, car bien sûr, tout cela se fait en binaire sous le capot, mais le point est, le nombre est représenté par les chiffres significatifs, plus un nombre qui représente la distance pour déplacer le radix (point décimal). Comme toujours, wikipedia peut vous donner plus de détails:
(Le deuxième lien est plus particulièrement axé sur votre cas particulier.)
Je pense que parce que dans le système binaire, 5 est périodique comme il n'est pas divisibles par 2. Et puis ce que Mark a dit Rushakoff applique.