451 Stimmen

Wie drucke ich einen Double-Wert mit voller Genauigkeit mit cout?

In meinem frühere Frage Ich druckte eine double mit cout das abgerundet wurde, als ich es nicht erwartet hatte. Wie kann ich die cout drucken a double mit voller Präzision?

492voto

Bill the Lizard Punkte 384619

Sie können die Genauigkeit direkt auf 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> um die maximale Genauigkeit eines Floats oder Doubles zu erhalten.

#include <limits>

typedef std::numeric_limits< double > dbl;

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

107voto

vitaut Punkte 42467

In C++20 werden Sie in der Lage sein, Folgendes zu verwenden std::format um dies zu tun:

std::cout << std::format("{}", M_PI);

Ausgang (unter der Annahme IEEE754 double ):

3.141592653589793

Das Standard-Gleitkommaformat ist die kürzeste Dezimaldarstellung mit einer Rundlaufgarantie. Der Vorteil dieser Methode im Vergleich zur setprecision E/A-Manipulator ist, dass er keine unnötigen Ziffern druckt.

In der Zwischenzeit können Sie die {fmt}-Bibliothek , std::format basiert auf. {fmt} bietet auch die print Funktion, die dies noch einfacher und effizienter macht ( godbolt ):

fmt::print("{}", M_PI);

Haftungsausschluss : Ich bin der Autor von {fmt} und C++20 std::format .

94voto

Paul Beckingham Punkte 13955

Utilice std::setprecision :

#include <iomanip>
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;

30voto

Martin York Punkte 245363

Das würde ich verwenden:

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

Das Paket "Limits" enthält im Grunde genommen Traits für alle eingebauten Typen.
Eines der Merkmale für Fließkommazahlen (float/double/long double) ist das Attribut digits10. Damit wird die Genauigkeit (ich habe die genaue Terminologie vergessen) einer Fließkommazahl zur Basis 10 definiert.

Siehe: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
Für Details über andere Attribute.

26voto

Wie drucke ich eine double Wert mit voller Genauigkeit mit cout?

Utilice hexfloat o
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 befassen sich nur mit einem der folgenden Punkte: 1) Basis, 2) feste/wissenschaftliche Anordnung oder 3) Präzision. Zu viele Antworten mit Präzision nicht den erforderlichen Wert liefern. Daher diese Antwort auf eine alte Frage.

  1. Welche Basis?

A double ist mit Sicherheit zur Basis 2 kodiert. Ein direkter Ansatz mit C++11 ist das Drucken mit std::hexfloat .
Wenn eine nicht dezimale 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 o scientific ?

A double ist eine Fließkomma Typ, nicht Festpunkt .

Do pas verwenden. std::fixed da diese nicht klein gedruckt werden kann double als alles andere als 0.000...000 . Für große double druckt er viele Ziffern, vielleicht Hunderte von zweifelhafter Aussagekraft.

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 Präzision zu drucken, verwenden Sie zunächst std::scientific die "Fließkommazahlen in wissenschaftlicher Notation schreibt". Beachten Sie die Vorgabe von 6 Stellen nach dem Komma, eine unzureichende Menge, die im nächsten Punkt behandelt wird.

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 hoch ist die Genauigkeit (wie viele Stellen insgesamt)?

A double die mit der Binärbasis 2 kodiert ist, kodiert die gleiche Genauigkeit zwischen verschiedenen Potenzen von 2. Dies sind häufig 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 .

Wenn der Code jedoch in dezimaler Form mit N signifikante Ziffern, die Anzahl der Kombinationen [1.0...10.0) ist 9/10 * 10 N .

Was auch immer N (Präzision) gewählt wird, gibt es keine Eins-zu-Eins-Abbildung zwischen double und dezimaler Text. Wenn eine feste N gewählt wird, wird sie manchmal etwas mehr oder weniger sein, als tatsächlich für bestimmte double Werte. Wir könnten uns an zu wenigen ( a) unten) oder zu viele ( b) unten).

3 Kandidaten N :

a) Verwenden Sie eine N so dass bei der Konvertierung von Text- in double -Text erhalten wir den gleichen Text für alle double .

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

b) Verwenden Sie eine N also bei der Konvertierung von double -Text- double kommen wir zu demselben double für alle double .

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

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

c) Verwenden Sie eine N die mit dem Wert variiert.

Dies kann nützlich sein, wenn der Code nur minimalen Text anzeigen will ( N == 1 ) oder die genau Wert einer double ( N == 1000-ish im Falle von denorm_min ). Da es sich hierbei jedoch um "Arbeit" und nicht um das Ziel von OP handelt, wird es beiseite gelassen.


In der Regel wird b) verwendet, um einen "Druck double Wert mit voller Präzision". Einige Anwendungen bevorzugen möglicherweise a), um nicht zu viele Informationen zu liefern.

Con .scientific , .precision() legt die Anzahl der Ziffern fest, die nach dem Dezimalkomma gedruckt werden, also 1 + .precision() Ziffern gedruckt werden. Code braucht max_digits10 Gesamtzahlen so .precision() wird aufgerufen mit einem 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
//2345678901234567  17 total digits

Ähnliche C-Frage

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X