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?

277
demandé sur Community 2009-02-16 21:15:18

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;
323
répondu Bill the Lizard 2018-09-13 12:18:13

Utilisation std::setprecision :

std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
52
répondu Paul Beckingham 2018-03-28 12:48:50

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.

22
répondu Martin York 2014-04-15 14:36:24

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

13
répondu Timothy003 2011-08-08 05:33:14

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

8
répondu Daniel Laügt 2016-01-02 11:58:53

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;
7
répondu Mark Lakata 2015-10-24 20:36:30
printf("%.12f", M_PI);

%.12f signifie point flottant, avec une précision de 12 chiffres.

2
répondu Maister 2010-01-24 17:34:56

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.

1
répondu Uri 2009-02-16 18:18:54

très probablement...

#include <limits>

using std::numeric_limits;

    ...
    cout.precision(numeric_limits<double>::digits10 + 1);
    cout << d;
0
répondu 2009-02-16 18:39:43

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.

0
répondu Jann 2009-08-11 11:28:59

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.

  1. 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

  1. sinon: fixed ou scientific ?

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

  1. 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

question similaire

0
répondu chux 2018-09-12 16:40:46