Comment puis-je imprimer une valeur double avec une précision maximale en utilisant la méthode cout?
donc j'ai eu la réponse à ma dernière question (Je ne sais pas pourquoi je n'y ai pas pensé). J'imprimais un double
en utilisant cout
qui a été arrondi quand je ne m'y attendais pas. Comment puis-je faire cout
imprimer un double
en utilisant la pleine précision?
11 réponses
vous pouvez régler la précision directement sur std::cout
et utiliser le spécificateur de format std::fixed
.
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;
Utilisation std::setprecision
:
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
voici ce que j'utiliserais:
std::cout << std::setprecision (std::numeric_limits<double>::digits10 + 1)
<< 3.14159265358979
<< std::endl;
fondamentalement le paquet limits a des traits pour tous les types de construction.
L'un des traits pour les nombres à virgule flottante (float/double/long double) est l'attribut digits10. Cela définit la précision (j'oublie la terminologie exacte) d'un nombre de virgule flottante en base 10.
voir: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
Pour plus de détails sur les autres attributs.
la voie iostream est un peu bouchée. Je préfère utiliser boost::lexical_cast
parce qu'il calcule la bonne précision pour moi. Et c'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 pleine précision:
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 différentes valeurs doubles. max_digits10 représente le nombre de chiffres avant et après la virgule.
N'utilisez pas set_precision(max_digits10) avec std::fixe.
Sur la notation Fixe, set_precision () fixe le nombre de chiffres seulement après le point décimal. C'est incorrect car max_digits10 représente le nombre de chiffres avant et après le point décimal.
double d = 100.0000000000005;
int precision = std::numeric_limits<double>::max_digits10;
std::cout << std::fixed << std::setprecision(precision) << d << std::endl;
cela affiche un résultat incorrect:
100.00000000000049738
par pleine précision, je suppose que moyenne assez de précision pour montrer la meilleure approximation à la valeur prévue, mais il faut souligner que double
est stocké en utilisant la représentation de base 2 et la base 2 ne peut pas représenter quelque chose d'aussi insignifiant que 1.1
exactement. La seule façon d'obtenir la précision full-full du double réel (sans erreur de arrondi) est d'imprimer les bits binaires (ou HEX nybbles). Une façon de le faire est d'écrire le double
à un union
et ensuite l'impression de la valeur entière des bits.
union {
double d;
uint64_t u64;
} x;
x.d = 1.1;
std::cout << std::hex << x.u64;
cela vous donnera la précision de 100% du double... et être tout à fait illisible parce que les humains ne peuvent pas lire le double format IEEE ! Wikipedia a une bonne écriture sur la façon d'interpréter les bits binaires.
dans le nouveau c++, vous pouvez faire
std::cout << std::hexfloat << 1.1;
printf("%.12f", M_PI);
%.12f signifie point flottant, 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 le formatage des documents imprimés.
Il y a un setprecision(... en fonctionnement, mais vous pouvez également définir d'autres choses comme la largeur d'impression, etc.
cherchez la référence de votre IDE.
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 devez dire "+1", je n'ai aucune idée, mais le chiffre supplémentaire pour vous est correct.
comment imprimer une valeur
double
avec une pleine précision en utilisant cout?
utiliser hexfloat
ou
utilisez scientific
et réglez 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
un trop grand nombre de réponses ne concernent qu'une seule des questions suivantes: 1) Base 2) disposition fixe/scientifique ou 3) Précision. Trop de réponses avec précision ne fournissent pas la valeur nécessaire. D'où cette réponse à une vieille question.
- quelle base?
a double
est certainement encodé 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 sommes faits.
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
- sinon:
fixed
ouscientific
?
Un double
est un à virgule flottante "1519680920 type", pas point fixe .
Faire pas utiliser std::fixed
dont il ne parvient pas à imprimer de petits double
0.000...000
. Pour grand double
, il imprime de nombreux chiffres, peut-être des centaines d'informativité discutable.
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 précision, première utilisation std::scientific
qui "écrira des valeurs à virgule flottante en notation scientifique". Notez que la valeur par défaut de 6 chiffres après le point décimal, un montant insuffisant, 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
- combien de précision (nombre total de chiffres)?
a double
encodé en utilisant la base binaire 2 code la même précision entre différentes puissances de 2. C'est souvent 53 bits.
[1.0...2.0) Il y a 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 2/8 * 2 53 différent double
.
encore si le code s'imprime décimal avec N
chiffres significatifs, le nombre de combinaisons [1.0...10,0) est de 9/10 * 10 N .
quelle que soit la précision choisie, il n'y aura pas de correspondance entre double
et le texte décimal. si un N
fixe est choisi, il sera parfois légèrement plus ou moins qu'il n'est réellement nécessaire pour certaines valeurs double
. Nous pourrions nous tromper sur trop peu ( a)
ci-dessous) ou trop ( b)
ci-dessous).
3 candidat N
:
a) utilisez un N
ainsi lors de la conversion de texte - double
- texte nous arrivons au même texte pour tous double
.
std::cout << dbl::digits10 << '\n';
// Typical output
15
b) utilisez un N
ainsi lors de la conversion de double
- texte - double
nous arrivons à la même double
pour tous double
.
// C++11
std::cout << dbl::max_digits10 << '\n';
// Typical output
17
quand max_digits10
n'est pas disponible, notez qu'en raison des attributs de base 2 et de base 10, digits10 + 2 <= max_digits10 <= digits10 + 3
, nous pouvons utiliser digits10 + 3
pour s'assurer que suffisamment de chiffres décimaux sont imprimés.
c) utilisez un N
qui varie avec la valeur.
cela peut être utile lorsque le code veut afficher un texte minimal ( N == 1
) ou la exacte valeur d'un double
( N == 1000-ish
dans le cas de denorm_min
). Pourtant, depuis c'est le "travail" et probablement pas L'objectif de L'OP, il sera mis de côté.
il est habituellement b) qui est utilisé pour" imprimer une double
valeur avec pleine précision". Certaines applications peuvent préférer un) à l'erreur de ne pas fournir trop d'informations.
avec .scientific
, .precision()
définit le nombre de chiffres à imprimer après le point décimal, ainsi 1 + .precision()
chiffres sont imprimés. Code needs max_digits10
total des chiffres donc .precision()
est appelé 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