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?
Antworten
Zu viele Anzeigen?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;
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
.
Utilice std::setprecision
:
#include <iomanip>
std::cout << std::setprecision (15) << 3.14159265358979 << std::endl;
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.
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.
- 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
- Ansonsten:
fixed
oscientific
?
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
- 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
- See previous answers
- Weitere Antworten anzeigen