Frage

Also habe ich die Antwort auf meine letzte Frage bekommen haben (I weiß nicht, warum ich nicht daran gedacht hätte). Ich war das Drucken eines double mit cout die abgerundet wurde, wenn ich es nicht erwartete. Wie kann ich cout Druck ein double mit voller Präzision machen?

War es hilfreich?

Lösung

Sie können die Genauigkeit direkt am std::cout und verwenden Sie die std::fixed Formatbezeichner.

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

Sie können #include <limits> die maximale Präzision eines Schwimmers oder Doppel zu erhalten.

#include <limits>

typedef std::numeric_limits< double > dbl;

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

Andere Tipps

Verwenden Sie std::setprecision :

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

Hier ist, was ich verwenden würde:

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

Grundsätzlich ist die Grenzen Paket hat Züge für alle Build-in-Typen.
Eines der Merkmale für Gleitkommazahlen (float / double / long double) ist die digits10 Attribut. Dies definiert die Genauigkeit (I vergessen, die genaue Terminologie) eine Gleitkommazahl in der Basis 10.

Siehe auch: http://www.cplusplus.com/reference/std/ Grenzen / numeric_limits.html
Einzelheiten zu anderen Attributen.

Die iostreams Art und Weise ist eine Art klobig. Ich ziehe mit boost::lexical_cast , weil es die richtige Präzision für mich berechnet. Und es ist schnell auch.

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

Ausgabe:

  

Pi: 3,14159265358979

Hier ist, wie ein Doppel mit voller Genauigkeit angezeigt werden:

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

Das zeigt:

  

100,0000000000005


max_digits10 ist die Anzahl der Stellen, die erforderlich sind, um eindeutig alle unterschiedlichen Doppel Werte darstellen. max_digits10 stellt die Anzahl der Stellen vor und nach dem Komma.


Nicht set_precision (max_digits10) mit std :: festgelegt.
Auf feste Notation, set_precision () setzt die Anzahl der Ziffern nur nach dem Komma. Dies ist falsch, wie max_digits10 die Anzahl der Ziffern repräsentiert vor und nach der Dezimalpunkt.

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

Dies zeigt falsches Ergebnis:

  

100,00000000000049738

Hinweis: Header-Dateien erforderlich

#include <iomanip>
#include <limits>

Mit voller Genauigkeit, gehe ich davon genug Präzision bedeuten die beste Annäherung an den gewünschten Wert zu zeigen, aber es sollte hingewiesen werden, dass double gespeichert wird mit der Basis 2 Darstellung und Basis 2 kann nicht gerade etwas so trivial, wie 1.1 darstellen. Der einzige Weg, um die full-full Genauigkeit der tatsächliche Doppel (mit NO Abrundungsfehler) zu erhalten, sind aus den binären Bits (oder Hex-Nibbles) zu drucken. Eine Möglichkeit, dies zu tun wird, um die double zu einem union schreiben und dann den ganzzahligen Wert der Bits auszudrucken.

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

Dies gibt Ihnen die 100% genaue Präzision der Doppel ... und seine völlig unleserlich, weil Menschen nicht IEEE Doppel Format lesen! Wikipedia hat eine gute aufzuschreiben, wie die binären Bits zu interpretieren.

In neueren C ++, können Sie

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

Wie kann ich einen double Wert mit voller Genauigkeit mit cout drucken?

Verwenden hexfloat oder in verwenden scientific und stellen Sie die Genauigkeit

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

Zu viele Antworten Adresse nur eines von 1) Basis 2) fest / wissenschaftliches Layout oder 3) Präzision. Zu viele Antworten mit Genauigkeit bieten nicht den richtigen Wert benötigt. Daher ist diese Antwort auf eine alte Frage.

  1. Welche Basis?
mit Basis 2. Ein direkter Ansatz

ist ein double sicher verschlüsselt mit C ++ 11 ist mit std::hexfloat zu drucken.
Wenn eine nichtdezimale Ausgabe akzeptabel ist, sind wir fertig.

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. Ansonsten: fixed oder scientific

A double ist ein Gleitkomma Typ, nicht Fixpunkt .

Do nicht Verwendung std::fixed wie kleine double als alles andere als 0.000...000 nicht gedruckt werden kann. Für großen double, druckt es viele Stellen, vielleicht Hunderte von fragwürdiger Aussage.

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 

Um mit voller Genauigkeit, die erste Gebrauch std::scientific zu drucken, die wird „Gleitkommazahlen in der wissenschaftlichen Schreibweise schreiben“. Beachten Sie die Standardeinstellung von 6 Stellen nach dem Komma, eine unzureichende Menge, wird im nächsten Punkt behandelt.

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. Wie viel Präzision (wie viele Gesamt Ziffern)?

A double die binäre Basis 2 codiert ist codiert die gleiche Präzision zwischen verschiedenen Potenzen von 2 Diese oft sind 53 Bits.

[1.0 ... 2.0) gibt es 2 53 verschiedene double,
[2.0 ... 4.0) gibt es 2 53 verschiedene double,
[4.0 ... 8.0) gibt es 2 53 verschiedene double,
[8.0 ... 10.0) gibt es 2/8 * 2 53 verschiedene double.

Doch wenn Code druckt in dezimal mit N signifikanten Stellen, die Anzahl der Kombinationen [1.0 ... 10.0) ist 9/10 * 10 N .

Was auch immer N (Präzision) gewählt wird, wird es keine Eins-zu-Eins-Abbildung zwischen double und Dezimal-Text sein. Wenn eine feste N gewählt wird, manchmal wird es etwas mehr oder weniger als wirklich für bestimmte double Werte benötigt. Wir konnten zu wenige Fehler auf (a) unten) oder zu viele (b) unten).

3 Kandidaten N:

a) Verwenden Sie so eine N wenn von Text-double-Text konvertieren wir den gleichen Text für alle double kommen.

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

b) Verwenden Sie so eine N, wenn sie von double-Text-double Umwandlung wir in der gleichen double für alle double kommen.

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

Wenn max_digits10 nicht verfügbar ist, beachten Sie, dass aufgrund der Basis 2 und der Basis 10 Attribute, digits10 + 2 <= max_digits10 <= digits10 + 3 wir digits10 + 3 verwenden können genügend Dezimalstellen werden gedruckt, um sicherzustellen.

c) Verwenden eines N die mit dem Wert variiert.

Dies kann nützlich sein, wenn der Code will minimalen Text (N == 1) oder die genau Wert eines double (N == 1000-ish im Fall von denorm_min) angezeigt werden soll. Doch da es sich um „Arbeit“ und nicht wahrscheinlich OP Ziel, wird es beiseite gesetzt werden.


Es ist in der Regel b), die verwendet wird, um „einen double Wert mit voller Genauigkeit zu drucken“. Einige Anwendungen können eine bevorzugen) auf Fehler auf nicht zu viel Informationen.

Mit .scientific, .precision() legt die Anzahl der Ziffern nach dem Komma zu drucken, so 1 + .precision() Ziffern gedruckt werden. Code Bedürfnisse max_digits10 Gesamt Ziffern so .precision() mit einem max_digits10 - 1 genannt wird.

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

ähnliche C Frage

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

%. 12f mittels Gleitkomma-, mit einer Genauigkeit von 12 Stellen.

cout ist ein Objekt, das eine Reihe von Methoden hat man nennen kann die Präzision und die Formatierung von gedruckten Sachen zu ändern.

Es gibt eine setprecision (...) Betrieb, aber Sie können auch andere Dinge wie Druckbreite eingestellt, etc.

Sehen Sie cout in Ihrer Referenz IDE.

Die meisten portably ...

#include <limits>

using std::numeric_limits;

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

Mit ostream :: Präzision (int)

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

nachgeben

3.141592653589793, 2.718281828459045

Warum Sie zu sagen haben „+1“ Ich habe keine Ahnung, aber die zusätzliche Ziffer, die Sie aus ihm heraus korrekt ist.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top