Question

J'ai obtenu la réponse à ma dernière question (I ne sais pas pourquoi je ne pensais pas que). Je l'impression d'un double en utilisant cout qui a obtenu arrondi quand je ne m'y attendais pas. Comment puis-je faire imprimer cout une double utilisant une précision complète?

Était-ce utile?

La solution

Vous pouvez définir la précision directement sur std::cout et utiliser le std::fixed spécificateur de format.

double d = 3.14159265358979;
cout.precision(17);
cout << "Pi: " << fixed << d << endl;

Vous pouvez #include <limits> pour obtenir la précision maximale d'un flotteur ou double.

#include <limits>

typedef std::numeric_limits< double > dbl;

double d = 3.14159265358979;
cout.precision(dbl::max_digits10);
cout << "Pi: " << d << endl;

Autres conseils

Utilisez std::setprecision :

std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;

Voici ce que j'utiliser:

std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
          << 3.14159265358979
          << std::endl;

Fondamentalement, le paquet a des traits limites pour tous les types de construction.
L'un des traits pour les nombres à virgule flottante (float / double / long double) est l'attribut digits10. Ceci définit la précision (j'oublie la terminologie exacte) d'un nombre à virgule flottante en base 10.

Voir: http://www.cplusplus.com/reference/std/ limites / numeric_limits.html
Pour plus de détails sur les autres attributs.

La façon iostream est un peu maladroit. Je préfère utiliser boost::lexical_cast car il calcule la précision pour moi. Et il est rapide aussi.

#include <string>
#include <boost/lexical_cast.hpp>

using boost::lexical_cast;
using std::string;

double d = 3.14159265358979;
cout << "Pi: " << lexical_cast<string>(d) << endl;

Sortie:

  

Pi: 3,14159265358979

Voici comment afficher un double avec une précision complète:

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::setprecision(precision) << d << std::endl;

Cette affiche:

  

100,0000000000005


max_digits10 est le nombre de chiffres qui sont nécessaires pour représenter de façon unique toutes les valeurs doubles distinctes. max_digits10 représente le nombre de chiffres avant et après la virgule.


Ne pas utiliser set_precision (max_digits10) avec std :: fixe. Sur notation fixe, set_precision () définit le nombre de chiffres seulement après la virgule. Ceci est incorrect que max_digits10 représente le nombre de chiffres avant et après la virgule.

double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;

affiche un résultat incorrect:

  

100,00000000000049738

Remarque: Les fichiers d'en-tête requis

#include <iomanip>
#include <limits>

En pleine précision, je suppose que dire assez de précision pour montrer la meilleure approximation à la valeur prévue, mais il convient de souligner que double est stockée en utilisant la base 2 et la représentation base 2 ne peut pas représenter quelque chose d'aussi trivial que 1.1 exactement. La seule façon d'obtenir le plein complet précision de la double réelle (sans Complètent erreur) est d'imprimer les bits binaires (ou quartets hexagonaux). Une façon de faire qui est en train d'écrire le double à un union puis l'impression de la valeur de nombre entier de bits.

union {
    double d;
    uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;

Cela vous donnera la précision précis à 100% de la double ... et être tout à fait illisible parce que les humains ne peuvent pas lire à double format IEEE! Wikipedia a une bonne écriture sur la façon d'interpréter les bits binaires.

Dans les nouvelles C ++, vous pouvez faire

std::cout << std::hexfloat << 1.1;
  

Comment puis-je imprimer une valeur double avec toute la précision en utilisant Cout?

Utilisez hexfloat ou
utiliser scientific et définir la précision

std::cout.precision(std::numeric_limits<double>::max_digits10 - 1);
std::cout << std::scientific <<  1.0/7.0 << '\n';

// C++11 Typical output
1.4285714285714285e-01

Trop de réponses ne portent que sur une des 1) base 2) mise en page fixe / scientifique ou 3) la précision. Trop de réponses avec précision ne fournissent pas la valeur correcte nécessaire. D'où cette réponse à une vieille question.

  1. Qu'est-ce que la base?

A double est certainement codé en utilisant la base 2. Une approche directe avec C ++ 11 est d'imprimer en utilisant std::hexfloat.
Si une sortie non décimale est acceptable, nous fait.

std::cout << "hexfloat: " << std::hexfloat << exp (-100) << '\n';
std::cout << "hexfloat: " << std::hexfloat << exp (+100) << '\n';
// output
hexfloat: 0x1.a8c1f14e2af5dp-145
hexfloat: 0x1.3494a9b171bf5p+144

  1. Dans le cas contraire: fixed ou scientific

A double est un virgule flottante type pas point fixe .

Do pas utiliser std::fixed que cela ne parvient pas à imprimer petite double comme tout sauf 0.000...000. Pour les grandes double, il imprime beaucoup de chiffres, peut-être des centaines de informativité douteux.

std::cout << "std::fixed: " << std::fixed << exp (-100) << '\n';
std::cout << "std::fixed: " << std::fixed << exp (+100) << '\n';
// output
std::fixed: 0.000000
std::fixed: 26881171418161356094253400435962903554686976.000000 

Pour imprimer avec une précision complète, première std::scientific d'utilisation qui « écrire des valeurs à virgule flottante en notation scientifique ». Notez la valeur par défaut de 6 chiffres après la virgule décimale, une quantité insuffisante, est traitée dans le point suivant.

std::cout << "std::scientific: " << std::scientific << exp (-100) << '\n';  
std::cout << "std::scientific: " << std::scientific << exp (+100) << '\n';
// output
std::scientific: 3.720076e-44
std::scientific: 2.688117e+43

  1. Combien de précision (combien de chiffres totaux)?

A double codé binaire en utilisant la base 2 code pour la même précision entre diverses puissances de 2. Ceci est souvent 53 bits.

[1.0 ... 2.0), il existe 2 53 différent double,
[2.0 ... 4.0) il y a 2 53 différent double,
[4.0 ... 8.0) il y a 2 53 différent double,
[8.0 ... 10.0) il y a 8.2 * 2 53 différent double.

Pourtant, si code imprime en décimal avec N chiffres significatifs, le nombre de combinaisons [1.0 ... 10.0) est 9/10 * 10 N .

Quelle que soit N (précision) est choisie, il n'y aura pas un à un entre double et texte décimal. Si un N fixe est choisie, il sera parfois un peu plus ou moins que vraiment nécessaire pour certaines valeurs double. On pourrait l'erreur trop peu (a) ci-dessous) ou trop (b) ci-dessous).

3 candidat N:

a) Utiliser un N donc lors de la conversion du texte double texte, nous arrivons au même texte pour tous double.

std::cout << dbl::digits10 << '\n';
// Typical output
15

b) Utiliser un N donc lors de la conversion de double texte-double nous arrivons au même double pour tous double.

// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17

Lorsque max_digits10 n'est pas disponible, notez qu'en raison de base 2 et la base 10 attributs, digits10 + 2 <= max_digits10 <= digits10 + 3, nous pouvons utiliser digits10 + 3 pour assurer suffisamment de chiffres décimaux sont imprimés.

c) Utiliser un N qui varie en fonction de la valeur.

Cela peut être utile lorsque le code veut afficher du texte minimal (N == 1) ou exactement valeur d'un double (N == 1000-ish dans le cas de denorm_min). Cependant, puisque c'est « travail » et non objectif de l'OP probable, il sera mis de côté.


Il est généralement b) qui est utilisé pour « imprimer une valeur de double avec une précision complète ». Certaines applications peuvent préférer a) à l'erreur sur ne pas fournir trop d'informations.

Avec .scientific, .precision() définit le nombre de chiffres à imprimer après le point décimal, donc les chiffres de 1 + .precision() sont imprimés. besoins du Code max_digits10 chiffres totaux si .precision() est appelée avec un max_digits10 - 1.

typedef std::numeric_limits< double > dbl;
std::cout.precision(dbl::max_digits10 - 1);
std::cout << std::scientific <<  exp (-100) << '\n';
std::cout << std::scientific <<  exp (+100) << '\n';
// Typical output
3.7200759760208361e-44
2.6881171418161356e+43

question similaire C

printf("%.12f", M_PI);

%. 12f moyens à virgule flottante, avec une précision de 12 chiffres.

Cout est un objet qui a un tas de méthodes que vous pouvez appeler pour changer la précision et la mise en forme de choses imprimées.

Il y a une opération SetPrecision (...), mais vous pouvez également définir d'autres choses comme la largeur d'impression, etc.

Recherchez dans Cout Référence de votre IDE.

La plupart portably ...

#include <limits>

using std::numeric_limits;

    ...
    cout.precision(numeric_limits<double>::digits10 + 1);
    cout << d;

Avec ostream :: précision (int)

cout.precision( numeric_limits<double>::digits10 + 1);
cout << M_PI << ", " << M_E << endl;

donnera

3.141592653589793, 2.718281828459045

Pourquoi vous avez à dire « +1 » Je n'ai aucune idée, mais le chiffre supplémentaire que vous en sortir est correct.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top