Also habe ich die Antwort auf meine letzte Frage bekommen (ich weiß nicht, warum ich nicht daran gedacht habe). Ich habe eine double
Verwendung gedruckt cout
, die gerundet wurde, als ich sie nicht erwartet hatte. Wie kann ich einen cout
Ausdruck double
mit voller Präzision erstellen?
331
fixed
? Mitdouble h = 6.62606957e-34;
,fixed
gibt mir0.000000000000000
undscientific
gibt aus6.626069570000000e-34
.cout.precision(numeric_limits<double>::digits10 + 2);
nur 16 ...max_digits10
, um dasselbe zu bezeichnen. Die Antwort wurde korrigiert, um dies widerzuspiegeln.Verwendung
std::setprecision
:quelle
std::setprecision (17)
doppelt sein, siehe Kommentare zu @ Bill The Lizard's Antwort.Folgendes würde ich verwenden:
Grundsätzlich enthält das Limits-Paket Merkmale für alle eingebauten Typen.
Eine der Eigenschaften für Gleitkommazahlen (float / double / long double) ist das Attribut digits10. Dies definiert die Genauigkeit (ich vergesse die genaue Terminologie) einer Gleitkommazahl in Basis 10.
Weitere Informationen zu anderen Attributen finden Sie unter: http://www.cplusplus.com/reference/std/limits/numeric_limits.html
.
quelle
std::setprecision()
:#include <iomanip>
std::numeric_limits<double>
stattnumberic_limits<double>
1
zustd::numeric_limits<double>::digits10
?max_digits10
stattdessen C + 11 verwenden. Sehen Sie das .max_digits10
nicht willkürlich seindigits10+2
. Andernfalls wird im Fallefloat
,long double
,boost::multiprecision::float128
wird dies nicht gelingen, da Sie bräuchten+3
statt+2
.Der iostreams Weg ist irgendwie klobig. Ich bevorzuge die Verwendung,
boost::lexical_cast
weil sie die richtige Präzision für mich berechnet. Und es ist auch schnell .Ausgabe:
quelle
Bei voller Genauigkeit gehe ich davon aus, dass die Genauigkeit genau genug ist, um die beste Annäherung an den beabsichtigten Wert zu zeigen, aber es sollte darauf hingewiesen werden, dass
double
die Verwendung unter Verwendung der Basis 2-Darstellung gespeichert wird und die Basis 2 nicht so trivial wie1.1
genau darstellen kann. Die einzige Möglichkeit, die volle Genauigkeit des tatsächlichen Doppels (ohne Abrundungsfehler) zu erhalten, besteht darin, die Binärbits (oder Hex-Nybbles) auszudrucken. Eine Möglichkeit, dies zu tun, besteht darin, dasdouble
in a zu schreibenunion
und dann den ganzzahligen Wert der Bits auszudrucken.Dies gibt Ihnen die 100% genaue Genauigkeit des Doppels ... und ist absolut unlesbar, da Menschen das IEEE-Doppelformat nicht lesen können! Wikipedia hat eine gute Beschreibung der Interpretation der Binärbits.
In neuerem C ++ können Sie dies tun
quelle
So zeigen Sie ein Double mit voller Präzision an:
Dies zeigt an:
max_digits10 ist die Anzahl der Stellen, die erforderlich sind, um alle unterschiedlichen Doppelwerte eindeutig darzustellen. max_digits10 steht für die Anzahl der Stellen vor und nach dem Dezimalpunkt.
Verwenden Sie set_precision (max_digits10) nicht mit std :: fixed.
Bei fester Notation legt set_precision () die Anzahl der Stellen erst nach dem Dezimalpunkt fest. Dies ist falsch, da max_digits10 die Anzahl der Stellen vor und nach dem Dezimalpunkt darstellt.
Dies zeigt ein falsches Ergebnis an:
Hinweis: Header-Dateien erforderlich
quelle
100.0000000000005
nicht genau als dargestellt wirddouble
. (Es mag so aussehen, als ob es sollte, aber es tut es nicht, weil es normalisiert wird , dh seine binäre Darstellung). Um dies zu sehen, versuchen Sie :100.0000000000005 - 100
. Wir bekommen4.973799150320701e-13
.Verwenden
hexfloat
oderverwenden
scientific
und stellen Sie die Präzision einZu viele Antworten sprechen nur eine von 1) Basis 2) festem / wissenschaftlichem Layout oder 3) Präzision an. Zu viele präzise Antworten liefern nicht den richtigen Wert. Daher diese Antwort auf eine alte Frage.
A
double
wird sicherlich mit Basis 2 codiert. Ein direkter Ansatz mit C ++ 11 besteht darin, mit zu druckenstd::hexfloat
.Wenn eine nicht dezimale Ausgabe akzeptabel ist, sind wir fertig.
fixed
oderscientific
?A
double
ist ein Gleitkommatyp , kein Festkomma .Verwenden Sie nicht ,
std::fixed
da dies nicht so kleindouble
wie alles andere als drucken kann0.000...000
. Im Großendouble
und Ganzen werden viele Ziffern gedruckt, möglicherweise Hunderte fragwürdiger Informationen.Um mit voller Präzision zu drucken, verwenden Sie zuerst
std::scientific
"Gleitkommawerte in wissenschaftlicher Notation schreiben". Beachten Sie, dass der Standardwert von 6 Stellen, nachdem der Dezimalpunkt, ein unzureichender Betrag, im nächsten Punkt behandelt wird.Eine
double
unter Verwendung der Binärbasis 2 codierte Codierung codiert die gleiche Genauigkeit zwischen verschiedenen Potenzen von 2. Dies sind häufig 53 Bit.[1.0 ... 2.0) es gibt 2 53 verschiedene
double
,[2.0 ... 4.0) es gibt 2 53 verschiedene
double
,[4.0 ... 8.0) es gibt 2 53 verschiedene
double
,[8.0 ... 10.0) es gibt 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 .Unabhängig von der
N
gewählten (Genauigkeit) erfolgt keine Eins-zu-Eins-Zuordnung zwischendouble
und Dezimaltext. Wenn ein FixN
ausgewählt wird, ist er manchmal für bestimmtedouble
Werte etwas mehr oder weniger als wirklich erforderlich . Wir könnten bei zu wenigen (a)
unten) oder zu vielen (b)
unten) Fehler machen .3 Kandidat
N
:a) Verwenden Sie ein
N
so, wenn Sie ausdouble
Text-Text konvertieren, erhalten wir für alle den gleichen Textdouble
.b) Verwenden Sie ein
N
so, wenn Sie vondouble
-text- konvertieren,double
wir kommendouble
für alle gleichdouble
.Wenn
max_digits10
nicht verfügbar, beachten Sie, dassdigits10 + 2 <= max_digits10 <= digits10 + 3
wir aufgrund der Attribute Basis 2 und Basis 10 verwenden könnendigits10 + 3
, dass genügend Dezimalstellen gedruckt werden.c) Verwenden Sie eine
N
, die mit dem Wert variiert.Dies kann nützlich sein, wenn Code minimalen Text (
N == 1
) oder den genauen Wert von adouble
(N == 1000-ish
im Fall vondenorm_min
) anzeigen möchte . Da dies jedoch "Arbeit" ist und wahrscheinlich nicht das Ziel von OP ist, wird es beiseite gelegt.Es wird normalerweise b) verwendet, um "einen
double
Wert mit voller Genauigkeit zu drucken ". Einige Anwendungen ziehen es möglicherweise vor, a) Fehler zu machen, wenn nicht zu viele Informationen bereitgestellt werden.Legt mit fest
.scientific
, wie.precision()
viele Stellen nach dem Dezimalpunkt1 + .precision()
gedruckt werden sollen , damit die Stellen gedruckt werden. Code benötigtmax_digits10
insgesamt Ziffern und wird daher.precision()
mit a aufgerufenmax_digits10 - 1
.Ähnliche C-Frage
quelle
precision()
die Anzahl der Dezimalstellen für den wissenschaftlichen Modus festgelegt wird. Ohne Angabescientific
wird die Gesamtzahl der Ziffern ohne Exponenten festgelegt. Abhängig von Ihrem Zahlenwert erhalten Sie möglicherweise immer noch wissenschaftliche Ergebnisse, aber dann erhalten Sie möglicherweise auch weniger Ziffern als angegeben. Beispiel: Diecout.precision(3); cout << 1.7976931348623158e+308; // "1.8e+308"
Ergebnisse fürprintf
können unterschiedlich sein. Verwirrende Dinge, auf die man achten sollte.char buf[DBL_DECIMAL_DIG + 3 + 5]; sprintf(buf, "%.*g", DBL_DECIMAL_DIG, d);
Die zusätzlichen Zeichen sind für: Vorzeichen, Dezimalpunkt, nachgestellte Null, e [+ | -], 3 Stellen für den Exponenten ( DBL_MAX_10_EXP = 308). Daher beträgt die Gesamtzahl der erforderlichen Zeichen 25.% .12f bedeutet Gleitkomma mit einer Genauigkeit von 12 Stellen.
quelle
Am tragbarsten ...
quelle
Mit ostream :: präzise (int)
wird nachgeben
Warum Sie "+1" sagen müssen Ich habe keine Ahnung, aber die zusätzliche Ziffer, die Sie daraus erhalten, ist korrekt.
quelle
Dies zeigt den Wert bis zu zwei Dezimalstellen nach dem Punkt an.
Siehe hier: Festkommanotation
std :: behoben
std :: setprecision
Wenn Sie mit dem IEEE-Standard zur Darstellung der Gleitkommazahlen vertraut sind, wissen Sie, dass es unmöglich ist, Gleitkommazahlen außerhalb des Geltungsbereichs des Standards mit voller Genauigkeit anzuzeigen , das heißt, dies führt immer dazu eine Rundung des realen Wertes.
Sie müssen zuerst prüfen, ob der Wert innerhalb des Bereichs liegt. Wenn ja, verwenden Sie:
std :: defaultfloat
Dies ist auch das Standardverhalten von
cout
, was bedeutet, dass Sie es nicht explizit verwenden.quelle