2010-03-18 2 views
0

J'utilise Visual C++ 2008 Express Edition et quand je déboguer le code:précision numérique de type double dans Visual C++ 2008 Express débogueur

double x = 0.2; 

que je vois dans le débogage infobulle sur x 0,20000000000000001

mais:

typedef numeric_limits<double> double_limit; 
int a = double_limit::digits10 

me donne: a = 15

Pourquoi les résultats dans débogueur sont plus t han normale C++ précision? Sur quoi repose cette étrange précision?

Mon CPU est Intel Core 2 Duo T7100

+6

Bienvenue à virgule flottante. – GManNickG

+1

Cette question (ou des variantes de) apparaît tous les quelques jours ici. Certainement une copie de quelque sorte! – spender

Répondre

1

Ce que vous voyez est causé par le fait que les chiffres réels (en lecture à virgule flottante) ne peut pas être exprimé avec une parfaite précision et précision dans les ordinateurs binaires. C'est un fait de la vie. Au lieu de cela, les ordinateurs approchent la valeur et la stockent en mémoire dans un format défini.

Dans le cas des machines les plus modernes (y compris toutes les machines sur lesquelles vous utilisez MSVC Express), ce format est IEEE 754. En résumé, voici comment les nombres réels sont stockés dans IEEE 754: il y a un bit de signe, 8 bits d'exposant et 23 bits de fraction (pour float type de données - doubles utiliser plus de bits en conséquence mais le format est le même). Pour cette raison, vous ne pouvez jamais atteindre une précision et une précision parfaites. Heureusement, vous pouvez obtenir beaucoup de précision et de précision pour presque toutes les applications, y compris les systèmes financiers critiques et les systèmes scientifiques.

Vous n'avez pas besoin de tout savoir sur IEEE754 afin de pouvoir utiliser des points flottants dans votre code. Mais il y a quelques choses que vous devez savoir:

1) Vous ne pouvez jamais comparer deux valeurs à virgule flottante pour l'égalité en raison de l'erreur d'arrondi inhérente à virgule flottante calulation stockage &. Au lieu de cela, vous devez faire quelque chose comme ceci:

double d = 0.2; 
double compare = 0.000000001; 

double d2 = something; 

if((d - d2 < compare) && (d2 - d < compare)) 
{ 
    // numbers are equal 
} 

2) Erreur d'arrondi composé. Plus vous effectuez d'opérations sur une valeur à virgule flottante, plus la perte de précision est importante.

3) Vous ne pouvez pas ajouter deux points flottants de magnitude très différente. Par exemple, vous ne pouvez pas ajouter 1.5x10^30 et 1.5x10^-30 et attendre 60 chiffres de précision.

0

La valeur exacte que le double littéral 0.2 vous donne est de 0,200000000000000011102230246251565404236316680908203125.

La plupart des fonctions doubles de sortie coupée après un certain nombre de chiffres décimaux, c'est la raison pour laquelle vous êtes dans l'illusion que 0.2 produit en fait 0,2

Voici comment je suis arrivé la valeur exacte:

public static void main(String[] args) 
{ 
    System.out.println(new java.math.BigDecimal(0.2)); 
} 
Questions connexes