Doppelte Genauigkeit – Dezimalstellen

Lesezeit: 7 Minuten

Doppelte Genauigkeit Dezimalstellen
nf313743

Nach dem, was ich gelesen habe, hat ein Wert vom Datentyp Double eine ungefähre Genauigkeit von 15 Dezimalstellen. Wenn ich jedoch eine Zahl verwende, deren Dezimaldarstellung sich wiederholt, z. B. 1,0/7,0, finde ich, dass die Variable den Wert 0,14285714285714285 enthält – das sind 17 Stellen (über den Debugger).

Ich würde gerne wissen, warum es intern als 17 Stellen dargestellt wird und warum eine Genauigkeit von 15 immer bei ~ 15 geschrieben wird?

  • Was hier relevant ist, ist das 1/7 ist eine rationale Zahl, deren Nenner aber keine Zweierpotenz ist.

    – Keith Thompson

    30. April 2013 um 23:28 Uhr

  • @johnnyturbo3 Eine rationale Zahl ist eine, die das Verhältnis zweier ganzer Zahlen ist. 1,0/7,0 ist das Verhältnis der ganzen Zahlen eins und sieben, also eindeutig rational. Alle rationalen Zahlen sind wiederkehrende Dezimalzahlen, in diesem Fall: .142857 142857 142857 usw. Irrationale Zahlen sind nicht das Verhältnis zweier ganzer Zahlen. Vielleicht aktualisieren Sie Ihre Frage, um das zu beheben?

    – Bruce Dawson

    28. November 2014 um 22:11 Uhr

  • Die ~15-Notation ist da, weil Sie nicht wirklich zwischen Dezimal- und Binärziffern konvertieren können. Zum Beispiel hat die Dezimalzahl 0,1 1 Dezimalziffer, aber sie ist binär periodisch, was bedeutet, dass Sie unendlich viele Binärziffern benötigen, um sie genau darzustellen. Im Allgemeinen ist jeder echte Bruch, dessen Nenner durch 5 geteilt werden kann, binär periodisch. (dasselbe gilt für 3 und 7, aber dann ist es auch dezimal periodisch)

    – Julio Franco

    17. Mai 2017 um 14:22 Uhr

1646640019 94 Doppelte Genauigkeit Dezimalstellen
Keith Thompson

Ein IEEE-Double hat 53 signifikante Bits (das ist der Wert von DBL_MANT_DIG in <cfloat>). Das sind etwa 15,95 Dezimalstellen (log10(253)); die Implementierungssätze DBL_DIG auf 15, nicht 16, weil es abgerundet werden muss. Sie haben also fast eine zusätzliche Dezimalstelle an Genauigkeit (über das hinaus, was durch impliziert wird DBL_DIG==15) deswegen.

Die nextafter() Funktion berechnet die nächste darstellbare Zahl zu einer gegebenen Zahl; Es kann verwendet werden, um zu zeigen, wie genau eine bestimmte Zahl ist.

Dieses Programm:

#include <cstdio>
#include <cfloat>
#include <cmath>

int main() {
    double x = 1.0/7.0;
    printf("FLT_RADIX = %d\n", FLT_RADIX);
    printf("DBL_DIG = %d\n", DBL_DIG);
    printf("DBL_MANT_DIG = %d\n", DBL_MANT_DIG);
    printf("%.17g\n%.17g\n%.17g\n", nextafter(x, 0.0), x, nextafter(x, 1.0));
}

gibt mir diese Ausgabe auf meinem System:

FLT_RADIX = 2
DBL_DIG = 15
DBL_MANT_DIG = 53
0.14285714285714282
0.14285714285714285
0.14285714285714288

(Sie können ersetzen %.17g durch, sagen wir, %.64g um mehr Ziffern zu sehen, von denen keine signifikant ist.)

Wie Sie sehen, ändert sich die letzte angezeigte Dezimalstelle mit jedem aufeinanderfolgenden Wert um 3. Die Tatsache, dass die letzte angezeigte Ziffer von 1.0/7.0 (5) zufällig mit dem mathematischen Wert übereinstimmt, ist weitgehend zufällig; es war ein Glücksfall. Und das Richtige gerundet Ziffer ist 6nicht 5. Ersetzen 1.0/7.0 durch 1.0/3.0 gibt diese Ausgabe:

FLT_RADIX = 2
DBL_DIG = 15
DBL_MANT_DIG = 53
0.33333333333333326
0.33333333333333331
0.33333333333333337

was eine Genauigkeit von etwa 16 Dezimalstellen zeigt, wie Sie es erwarten würden.

  • Diese Antwort unterscheidet nicht eindeutig zwischen der Anzahl der Dezimalstellen, die erforderlich sind, um ein Double (17 Stellen) eindeutig zu identifizieren, und der Anzahl der Dezimalstellen, die ein Double eindeutig identifizieren kann (15 Stellen). Dies ist entscheidend und wird in anderen Antworten besser behandelt. Hier gehe ich näher darauf ein: randomascii.wordpress.com/2012/03/08/…

    – Bruce Dawson

    28. November 2014 um 22:03 Uhr


1646640020 987 Doppelte Genauigkeit Dezimalstellen
Wahrhaftigkeit

Es sind eigentlich 53 Binärstellen, was 15 stabile Dezimalstellen bedeutet, was bedeutet, dass wenn Sie eine Zahl mit 15 Dezimalstellen runden, wandeln Sie sie in a um doubleund dann um die double Zurück zu 15 Dezimalstellen erhalten Sie die gleiche Zahl. Zur eindeutigen Darstellung von a double Sie benötigen 17 Dezimalstellen (was bedeutet, dass es für jede Zahl mit 17 Dezimalstellen eine eindeutige nächste gibt double), weshalb 17 Stellen angezeigt werden, aber nicht alle 17-Dezimalzahlen unterschiedlich zugeordnet sind double Werte (wie in den Beispielen in den anderen Antworten).

  • Es bedeutet 15 stabil Integral- Dezimal Ziffern vor der Dezimalstelle, in an ganze Zahl. Wenn es um Brüche geht, sind alle Wetten ungültig. Zum Beispiel 3 hat eine signifikante Ziffer, aber 1/3 == 0.333333333333333 die unendlich viele Nachkommastellen hat. Dasselbe passiert in binär.

    – Benutzer207421

    21. Oktober 2017 um 0:41 Uhr

Doppelte Genauigkeit Dezimalstellen
John Calsbeek

Die Dezimaldarstellung von Fließkommazahlen ist etwas seltsam. Wenn Sie eine Zahl mit 15 Dezimalstellen haben und diese in a umwandeln double, dann drucke es mit genau 15 Dezimalstellen aus, du solltest dieselbe Zahl erhalten. Auf der anderen Seite, wenn Sie eine beliebige ausdrucken double mit 15 Dezimalstellen und wandeln Sie es zurück in a doubleerhalten Sie nicht unbedingt den gleichen Wert zurück – den Sie brauchen 17 Nachkommastellen dafür. Und weder 15 noch 17 Dezimalstellen reichen aus, um das exakte Dezimaläquivalent einer beliebigen Zahl genau anzuzeigen double. Im Allgemeinen benötigen Sie über 100 Dezimalstellen das genau zu machen.

Sehen die Wikipedia-Seite für doppelte Genauigkeit und das Artikel über Fließkommagenauigkeit.

  • Haben Sie eine Referenz bezüglich “über 100 Dezimalstellen”? Ich kann sehen, wie Sie vielleicht 63 brauchen, aber mehr als das?

    – Wahrhaftigkeit

    3. April 2012 um 19:04 Uhr

  • @trutheality Mein zweiter Link ganz unten ist, woher ich diese Nummer habe.

    – John Calsbeek

    3. April 2012 um 19:06 Uhr

  • Wow, ich habe gar nicht darüber nachgedacht, wie viel der Exponent beitragen kann. Danke!

    – Wahrhaftigkeit

    3. April 2012 um 19:11 Uhr

  • @John Calsbeek Die Statistik “über 100 Dezimalstellen” aus dem Artikel, auf den Sie verweisen, gilt für Floats. Doubles benötigen mehr als 750 signifikante Stellen.

    – Rick Regan

    4. April 2012 um 1:30 Uhr

  • Aber die 100/750-Ziffern werden unter der Annahme benötigt, dass die Fließkommadarstellung der betreffenden tatsächlichen Zahl genau ist, ansonsten dienen die zusätzlichen Ziffern nur der Nachwelt (dh sie haben keine tatsächliche Bedeutung).

    – rubenvb

    25. September 2017 um 10:36 Uhr

1646640023 499 Doppelte Genauigkeit Dezimalstellen
Muhende Ente

Ein Double enthält genau 53 Binärziffern, was ~15,9545898 Dezimalziffern entspricht. Der Debugger kann beliebig viele Ziffern anzeigen, um genauer zu sein binär Wert. Oder es könnte dauern weniger Ziffern und binär, wie 0,1 nimmt 1 Ziffer zur Basis 10, aber unendlich zur Basis 2.

Das ist seltsam, also zeige ich ein extremes Beispiel. Wenn wir einen supereinfachen Gleitkommawert erstellen, der nur 3 Binärziffern Genauigkeit und keine Mantisse oder Vorzeichen enthält (der Bereich liegt also zwischen 0 und 0,875), sind unsere Optionen:

binary - decimal
000    - 0.000
001    - 0.125
010    - 0.250
011    - 0.375
100    - 0.500
101    - 0.625
110    - 0.750
111    - 0.875

Aber wenn Sie die Zahlen machen, ist dieses Format nur auf 0,903089987 Dezimalstellen genau. Nicht einmal 1 Ziffer ist genau. Wie leicht zu sehen ist, da es keinen Wert gibt, der mit beginnt 0.4?? Noch 0.9??und um dennoch die volle Genauigkeit anzuzeigen, benötigen wir 3 Dezimalstellen.

tl; dr: Der Debugger zeigt Ihnen den Wert der Gleitkommavariable mit einer willkürlichen Genauigkeit (in Ihrem Fall 19 Ziffern), was nicht unbedingt mit der Genauigkeit des Gleitkommaformats (in Ihrem Fall 17 Ziffern) korreliert.

1646640024 264 Doppelte Genauigkeit Dezimalstellen
Jerry Sarg

IEEE 754-Gleitkommazahlen werden binär ausgeführt. Es gibt keine exakte Umrechnung von einer bestimmten Anzahl von Bits in eine bestimmte Anzahl von Dezimalstellen. 3 Bits können Werte von 0 bis 7 halten, und 4 Bits können Werte von 0 bis 15 halten. Ein Wert von 0 bis 9 nimmt an grob 3,5 Bit, aber das ist auch nicht exakt.

Eine IEEE 754-Zahl mit doppelter Genauigkeit belegt 64 Bit. Davon sind 52 Bits dem Signifikanten gewidmet (der Rest ist ein Vorzeichenbit und ein Exponent). Da der Signifikand (normalerweise) normalisiert ist, gibt es eine implizierte 53rd bisschen.

Bei 53 Bit und ungefähr 3,5 Bit pro Ziffer ergibt eine einfache Division eine Genauigkeit von 15,1429 Ziffern. Denken Sie jedoch daran, dass 3,5 Bit pro Dezimalstelle nur eine Annäherung und keine absolut genaue Antwort sind.

Viele (die meisten?) Debugger betrachten tatsächlich den Inhalt des gesamten Registers. Auf einem x86 ist das eigentlich eine 80-Bit-Zahl. Die x86-Gleitkommaeinheit wird normalerweise so angepasst, dass sie Berechnungen mit 64-Bit-Präzision durchführt – aber intern verwendet sie tatsächlich ein paar „Wächterbits“, was im Grunde bedeutet, dass sie die Berechnung intern mit ein paar zusätzlichen Bits an Genauigkeit durchführt es kann das letzte korrekt runden. Wenn der Debugger das gesamte Register durchsucht, findet er normalerweise mindestens eine zusätzliche Ziffer, die ziemlich genau ist – da diese Ziffer jedoch keine Schutzbits hat, wird sie möglicherweise nicht korrekt gerundet.

1646640025 617 Doppelte Genauigkeit Dezimalstellen
spencercw

Das liegt daran, dass es von einer binären Darstellung konvertiert wird. Nur weil es all diese Dezimalziffern gedruckt hat, bedeutet das nicht, dass es alle Dezimalwerte mit dieser Genauigkeit darstellen kann. Nehmen Sie zum Beispiel dies in Python:

>>> 0.14285714285714285
0.14285714285714285
>>> 0.14285714285714286
0.14285714285714285

Beachten Sie, wie ich die letzte Ziffer geändert habe, aber trotzdem dieselbe Zahl ausgedruckt wurde.

1646640028 858 Doppelte Genauigkeit Dezimalstellen
Superkatze

In den meisten Kontexten wo double Werte verwendet werden, haben die Berechnungen eine gewisse Unsicherheit. Die Differenz zwischen 1,33333333333333300 und 1,33333333333333399 kann geringer sein als die Unsicherheit, die in den Berechnungen besteht. Den Wert von „2/3 + 2/3“ als „1.33333333333333“ anzuzeigen, ist wahrscheinlich aussagekräftiger als die Anzeige als „1.33333333333333319“, da die letztere Anzeige eine Genauigkeit impliziert, die nicht wirklich vorhanden ist.

Im Debugger ist es jedoch wichtig, den Wert einer Variablen eindeutig anzugeben, einschließlich im Wesentlichen bedeutungsloser Bits an Präzision. Es wäre sehr verwirrend, wenn ein Debugger zwei Variablen mit dem Wert “1.333333333333333” anzeigen würde, wenn eine von ihnen tatsächlich 1.33333333333333319 und die andere 1.33333333333333294 enthielt (was bedeutet, dass sie zwar gleich aussahen, aber nicht gleich waren). Die vom Debugger angezeigte zusätzliche Genauigkeit ist nicht geeignet, ein numerisch korrektes Berechnungsergebnis darzustellen, sondern gibt an, wie der Code die von den Variablen gehaltenen Werte interpretiert.

964190cookie-checkDoppelte Genauigkeit – Dezimalstellen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy