2015-07-17 4 views
1

Voici ce que je pense:Pourquoi la précision par défaut de cout n'affecte pas le résultat évalué?

#include <iostream> 
#include <iomanip> 

    int main() 
{ 
    double x = 10-9.99; 
    std::cout << x << std::endl; 
    std::cout << std::setprecision (16); 
    std::cout << x; 
    return 0; 
    } 

Le programme imprime au-dessus de 0,01 en évaluant x avant SetPrecision() et un long nombre qui est pas exactement égal à 0,01, pour x après SetPrecision() .cout a la précision par défaut de 16 lors de l'impression de nombres à virgule flottante dans ma machine. Si la précision est de 16, la valeur ci-dessus devrait être quelque chose comme 0.0100000000000000 mais il reste 0.01 mais quand je prends la valeur (16), le programme imprime un nombre long contenant 16 chiffres. Donc ma question est, pourquoi cout n'imprime pas tous les chiffres selon les types de précision par défaut. Pourquoi avons-nous besoin de forcer cout (en utilisant setprecision()) pour imprimer tous les chiffres? Pourquoi cout n'imprime pas tous les chiffres en fonction de la précision par défaut des types.

+0

Utilisez 'setw' pour définir le nombre de chiffres que vous voulez afficher –

+0

* cout a une précision par défaut de 16 lors de l'impression de nombres à virgule flottante sur ma machine. * Qu'est-ce qui vous fait penser cela? –

+0

@R Sahu Je pense que la précision par défaut de cout lors de l'impression double, peut être 15, 16 ou 17. Il est spécifique au compilateur. –

Répondre

1

Si vous utilisez std::fixed ainsi que setprecision, il affiche cependant, de chiffres de la précision, sans vous demande d'arrondi et troncature.

Quant à savoir pourquoi les comptes d'arrondissement pour la sortie ...

Obtenons votre code d'imprimer un couple d'autres choses aussi:

#include <iostream> 
#include <iomanip> 

int main() 
{ 
    double x = 10-9.99; 
    std::cout << x << '\n'; 
    std::cout << std::setprecision (16); 
    std::cout << x << '\n'; 
    std::cout << 0.01 << '\n'; 
    std::cout << std::setprecision (18); 
    std::cout << x << '\n'; 
    std::cout << 0.01 << '\n'; 
    std::cout << x - 0.01 << '\n'; 
} 

et la sortie (sur un compilateur/système spécifique) :

0.01 // x default 
0.009999999999999787 // x after setprecision(16) 
0.01 // 0.01 after setprecision(16) 
0.00999999999999978684 // x after setprecision(18) 
0.0100000000000000002 // 0.01 after setprecision(18) 
-2.13370987545147273e-16 // x - 0.01 

Si nous regardons comment 0,01 est encodées directement à une précision de 18 chiffres ...

0.0100000000000000002 
    123456789// counting digits 

... on voit clairement pourquoi il pourrait se tronqué à "0.01" lors de la sortie à une précision jusqu'à 17

Vous pouvez aussi voir clairement qu'il ya une valeur différente x à celui créé par le codage directement 0.01 - cela est autorisé parce que c'est le résultat d'un calcul, et dépendant d'une approximation double ou d'un registre CPU de 9.99, l'un ou l'autre ayant causé la différence. Cette erreur est suffisante pour éviter l'arrondissement à "0.01" à la précision 16.

Malheureusement, ce genre de chose est normal lors de la manipulation double s et float s.