Domanda

Quindi ho ottenuto la risposta al mio ultima domanda (Non so perché non ci ho pensato).Stavo stampando un double utilizzando cout è stato arrotondato quando non me lo aspettavo.Come posso fare cout stampa a double utilizzando la massima precisione?

È stato utile?

Soluzione

È possibile impostare la precisione direttamente sul std::cout e utilizzare il std::fixed di formato.

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

È possibile #include <limits> per ottenere la massima precisione di un galleggiante o doppia.

#include <limits>

typedef std::numeric_limits< double > dbl;

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

Altri suggerimenti

std::setprecision :

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

Ecco quello che vorrei utilizzare:

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

In sostanza il pacchetto limiti ha dei tratti per tutta la configurazione in tipi.
Uno dei tratti per i numeri in virgola mobile (float / double / long double) è l'attributo digits10. Questo definisce la precisione (ho dimenticato la terminologia esatta) di un numero decimale in base 10.

See: http://www.cplusplus.com/reference/std/ limiti / numeric_limits.html
Per informazioni dettagliate su altri attributi.

Il modo iostreams è una specie di goffo. Io preferisco usare boost::lexical_cast perché calcola la giusta precisione per me. E è veloce , anche.

#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;

Output:

  

Pi: 3,14159265358979

Ecco come visualizzare una doppia con precisione completa:

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

Questa mostra:

  

100,0000000000005


max_digits10 è il numero di cifre che sono necessari per rappresentare univocamente tutti i valori doppi distinti. max_digits10 rappresenta il numero di cifre prima e dopo il punto decimale.


Non utilizzare set_precision (max_digits10) con std :: fisso.
Su notazione fissa, set_precision () imposta il numero di cifre solo dopo il punto decimale. Ciò è corretto come max_digits10 rappresenta il numero di cifre prima e dopo il punto decimale.

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

Questa mostra risultato errato:

  

100,00000000000049738

Nota: i file header necessari

#include <iomanip>
#include <limits>

Con precisione piena, suppongo che significa precisione sufficiente per mostrare la migliore approssimazione al valore previsto, ma va sottolineato che è memorizzato double utilizzando la rappresentazione base 2 e la base 2 non può rappresentare qualcosa di così banale come 1.1 esattamente. L'unico modo per ottenere il pieno intero precisione dell'effettiva doppia (con NO errore inerente) è quello di stampare i bit binari (o nybbles esadecimali). Un modo di fare che sta scrivendo la double ad un union e poi stampare il valore intero dei bit.

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

Questo vi darà il 100% di precisione accurata del doppio ... ed essere assolutamente illeggibile perché gli esseri umani non possono leggere IEEE formato doppio! Wikipedia ha una buona scrittura su come interpretare i bit binari.

In più recente C ++, si può fare

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

Come faccio a stampare un double valore con la massima precisione utilizzando cout?

Utilizzo hexfloat O
utilizzo scientific e impostare la precisione

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

Troppe risposte riguardano solo una tra 1) base 2) layout fisso/scientifico o 3) precisione.Troppe risposte con precisione non fornire il valore corretto necessario.Da qui questa risposta ad una vecchia domanda.

  1. Quale base?

UN double è certamente codificato utilizzando la base 2.Un approccio diretto con C++11 consiste nel stampare utilizzando std::hexfloat.
Se un output non decimale è accettabile, abbiamo finito.

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. Altrimenti: fixed O scientific?

UN double è un virgola mobile tipo, no Punto fisso.

Fare non utilizzo std::fixed poiché non riesce a stampare in piccolo double come tutt'altro 0.000...000.Per grandi double, stampa molte cifre, forse centinaia di discutibile informatività.

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 

Per stampare con la massima precisione, utilizzare prima std::scientific che "scriverà valori in virgola mobile in notazione scientifica".Si noti che il valore predefinito di 6 cifre dopo il punto decimale, una quantità insufficiente, viene gestito nel punto successivo.

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. Quanta precisione (quante cifre totali)?

UN double codificato utilizzando la base binaria 2 codifica la stessa precisione tra varie potenze di 2.Questo è spesso 53 bit.

[1.0...2.0) ce ne sono 253 diverso double,
[2.0...4.0) ce ne sono 253 diverso double,
[4.0...8.0) ce ne sono 253 diverso double,
[8.0...10.0) ci sono 2/8 * 253 diverso double.

Tuttavia, se il codice viene stampato in formato decimale con N cifre significative, il numero di combinazioni [1.0...10.0) è 9/10 * 10N.

Qualunque cosa N (precisione), non ci sarà una mappatura uno a uno tra double e testo decimale. Se un fisso N viene scelto, a volte sarà leggermente più o meno di quanto realmente necessario per certo double valori.Potremmo sbagliare su troppo pochi (a) sotto) o troppi (b) sotto).

3 candidati N:

a) Utilizzare un N quindi quando si converte da testo-double-text arriviamo allo stesso testo per tutti double.

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

b) Utilizzare un N quindi durante la conversione da double-testo-double arriviamo allo stesso double per tutti double.

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

Quando max_digits10 non è disponibile, tieni presente che a causa degli attributi base 2 e base 10, digits10 + 2 <= max_digits10 <= digits10 + 3, possiamo usare digits10 + 3 per garantire che vengano stampate abbastanza cifre decimali.

c) Utilizzare un N che varia con il valore.

Questo può essere utile quando il codice vuole visualizzare un testo minimo (N == 1) o il esatto valore di a double (N == 1000-ish in caso di denorm_min).Tuttavia, poiché questo è un "lavoro" e probabilmente non l'obiettivo dell'OP, verrà messo da parte.


Di solito è b) che viene utilizzato per "stampare a double valore con la massima precisione".Alcune applicazioni potrebbero preferire a) all'errore di non fornire troppe informazioni.

Con .scientific, .precision() imposta il numero di cifre da stampare dopo il punto decimale, quindi 1 + .precision() le cifre vengono stampate.Esigenze del codice max_digits10 cifre totali così .precision() si chiama con a 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

Domanda C simile

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

%. 12f mezzi virgola mobile, con precisione di 12 cifre.

cout è un oggetto che ha un sacco di metodi che è possibile chiamare per modificare la precisione e la formattazione di roba stampata.

C'è un setprecision (...) il funzionamento, ma è anche possibile impostare altre cose come larghezza di stampa, ecc.

Look up cout riferimento del vostro IDE.

La maggior parte portabile ...

#include <limits>

using std::numeric_limits;

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

Con ostream :: precisione (int)

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

produrrà

3.141592653589793, 2.718281828459045

Perché avete da dire "+1" Non ho idea, ma la cifra più si ottiene fuori di esso è corretto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top