Großer Unterschied.
Wie der Name schon sagt, double
hat a die doppelte Genauigkeit von [1] . Im Allgemeinen hat a eine Genauigkeit von 15 Dezimalstellen, während a 7 hat.float
double
float
So wird die Anzahl der Ziffern berechnet:
double
hat 52 Mantissenbits + 1 verstecktes Bit: log (2 53 ) ÷ log (10) = 15,95 Stellen
float
hat 23 Mantissenbits + 1 verstecktes Bit: log (2 24 ) ÷ log (10) = 7,22 Stellen
Dieser Präzisionsverlust könnte dazu führen, dass sich größere Wiederholungsfehler ansammeln, wenn wiederholte Berechnungen durchgeführt werden, z
float a = 1.f / 81;
float b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.7g\n", b); // prints 9.000023
während
double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i)
b += a;
printf("%.15g\n", b); // prints 8.99999999999996
Auch der Maximalwert von float ist ungefähr 3e38
, aber double ist ungefähr 1.7e308
, so dass die Verwendung von float
"unendlich" (dh eine spezielle Gleitkommazahl) viel einfacher getroffen werden kann als double
für etwas Einfaches, z. B. die Berechnung der Fakultät von 60.
Während des Testens enthalten möglicherweise einige Testfälle diese großen Zahlen, die dazu führen können, dass Ihre Programme fehlschlagen, wenn Sie Floats verwenden.
Natürlich ist manchmal sogar double
nicht genau genug, daher haben wir manchmal long double
[1] (das obige Beispiel gibt 9.00000000000000000066 auf dem Mac an), aber alle Gleitkommatypen leiden unter Rundungsfehlern , wenn also Präzision sehr wichtig ist (z. B. Geld) Verarbeitung) sollten Sie int
oder eine Bruchklasse verwenden.
Verwenden Sie außerdem nicht +=
viele Gleitkommazahlen, da sich die Fehler schnell ansammeln. Wenn Sie Python verwenden, verwenden Sie fsum
. Versuchen Sie andernfalls, den Kahan-Summationsalgorithmus zu implementieren .
[1]: Die C- und C ++ Standards spezifizieren nicht die Darstellung float
, double
und long double
. Es ist möglich, dass alle drei als IEEE-Doppelgenauigkeit implementiert sind. Für die meisten Architekturen (gcc, MSVC; x86, x64, ARM) float
handelt es sich jedoch tatsächlich um eine IEEE-Gleitkommazahl mit einfacher Genauigkeit (binary32) und double
um eine IEEE-Gleitkommazahl mit doppelter Genauigkeit (binary64).
In den Normen C99 (ISO-IEC 9899 6.2.5 §10) oder C ++ 2003 (ISO-IEC 14882-2003 3.1.9 §8) heißt es:
Der C ++ - Standard fügt hinzu:
Ich würde vorschlagen, einen Blick auf das ausgezeichnete zu werfen, was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte , das den IEEE-Gleitkomma-Standard ausführlich behandelt. Sie lernen die Details der Darstellung kennen und stellen fest, dass es einen Kompromiss zwischen Größe und Präzision gibt. Die Genauigkeit der Gleitkommadarstellung nimmt mit abnehmender Größe zu, daher sind Gleitkommazahlen zwischen -1 und 1 diejenigen mit der höchsten Genauigkeit.
quelle
Bei einer quadratischen Gleichung: x 2 - 4.0000000 x + 3.9999999 = 0 sind die genauen Wurzeln zu 10 signifikanten Stellen r 1 = 2.000316228 und r 2 = 1.999683772.
Mit
float
unddouble
können wir ein Testprogramm schreiben:Das Ausführen des Programms gibt mir:
Beachten Sie, dass die Zahlen nicht groß sind, Sie jedoch dennoch Stornierungseffekte verwenden
float
.(Tatsächlich ist das Obige nicht der beste Weg, um quadratische Gleichungen mit Gleitkommazahlen mit einfacher oder doppelter Genauigkeit zu lösen, aber die Antwort bleibt unverändert, selbst wenn man eine stabilere Methode verwendet .)
quelle
quelle
Die Größe der Zahlen, die an den Gleitkommaberechnungen beteiligt sind, ist nicht die relevanteste Sache. Es ist die Berechnung, die durchgeführt wird, die relevant ist.
Wenn Sie eine Berechnung durchführen und das Ergebnis eine irrationale Zahl oder eine wiederkehrende Dezimalzahl ist, treten im Wesentlichen Rundungsfehler auf, wenn diese Zahl in die von Ihnen verwendete Datenstruktur endlicher Größe gequetscht wird. Da double doppelt so groß ist wie float, ist der Rundungsfehler viel kleiner.
Bei den Tests werden möglicherweise speziell Zahlen verwendet, die diese Art von Fehler verursachen würden. Daher wurde getestet, ob Sie den entsprechenden Typ in Ihrem Code verwendet haben.
quelle
Der 32-Bit-Typ float hat eine Genauigkeit von 7 Stellen. Während es Werte mit sehr großem oder sehr kleinem Bereich (+/- 3,4 * 10 ^ 38 oder * 10 ^ -38) speichern kann, hat es nur 7 signifikante Stellen.
Typ double, 64 Bit lang, hat einen größeren Bereich (* 10 ^ + / - 308) und eine Genauigkeit von 15 Stellen.
Der Typ long double ist nominell 80 Bit, obwohl eine bestimmte Compiler / OS-Paarung ihn zu Ausrichtungszwecken als 12-16 Byte speichern kann. Das lange Doppel hat einen Exponenten, der einfach lächerlich groß ist und eine Genauigkeit von 19 Stellen haben sollte. Microsoft begrenzt in ihrer unendlichen Weisheit das lange Double auf 8 Bytes, genau wie das einfache Double.
Verwenden Sie im Allgemeinen nur den Typ double, wenn Sie einen Gleitkommawert / eine Gleitkommavariable benötigen. In Ausdrücken verwendete wörtliche Gleitkommawerte werden standardmäßig als Doppelwerte behandelt, und die meisten mathematischen Funktionen, die Gleitkommawerte zurückgeben, geben Doppelwerte zurück. Sie sparen sich viele Kopfschmerzen und Typografien, wenn Sie nur double verwenden.
quelle
Ich bin gerade auf einen Fehler gestoßen, der mich ewig gekostet hat, um herauszufinden, und der Ihnen möglicherweise ein gutes Beispiel für die Float-Präzision geben kann.
Die Ausgabe ist
Wie Sie nach 0,83 sehen können, nimmt die Genauigkeit erheblich ab.
Wenn ich mich jedoch
t
als Double einrichte , tritt ein solches Problem nicht auf.Ich habe fünf Stunden gebraucht, um diesen kleinen Fehler zu erkennen, der mein Programm ruiniert hat.
quelle
double
ist hier keine gute Lösung. Sie verwenden, umint
zu zählen und eine interne Multiplikation durchzuführen, um Ihren Gleitkommawert zu erhalten.Schwimmer haben eine geringere Präzision als Doppelschwimmer. Obwohl Sie bereits wissen, lesen Sie zum besseren Verständnis , was wir über Gleitkomma-Arithmetik wissen sollten .
quelle
Wenn Sie Gleitkommazahlen verwenden, können Sie nicht darauf vertrauen, dass Ihre lokalen Tests genau den Tests entsprechen, die auf der Serverseite durchgeführt werden. Die Umgebung und der Compiler unterscheiden sich wahrscheinlich auf Ihrem lokalen System und dort, wo die endgültigen Tests ausgeführt werden. Ich habe dieses Problem schon oft in einigen TopCoder-Wettbewerben gesehen, insbesondere wenn Sie versuchen, zwei Gleitkommazahlen zu vergleichen.
quelle
Die integrierten Vergleichsoperationen unterscheiden sich wie beim Vergleichen von 2 Zahlen mit Gleitkommazahlen. Der Unterschied im Datentyp (dh Float oder Double) kann zu unterschiedlichen Ergebnissen führen.
quelle
Wenn man mit eingebetteter Verarbeitung arbeitet, wird die zugrunde liegende Hardware (z. B. FPGA oder ein bestimmtes Prozessor- / Mikrocontroller-Modell) möglicherweise optimal in Hardware implementiert, während double Softwareroutinen verwendet. Wenn also die Genauigkeit eines Floats ausreicht, um die Anforderungen zu erfüllen, wird das Programm mit float einige Male schneller ausgeführt als mit double. Achten Sie, wie in anderen Antworten angegeben, auf Akkumulationsfehler.
quelle
Im Gegensatz zu einer
int
(ganzen Zahl) hat afloat
einen Dezimalpunkt, und a auchdouble
. Der Unterschied zwischen den beiden besteht jedoch darin, dass adouble
doppelt so detailliert ist wie afloat
, was bedeutet, dass es nach dem Dezimalpunkt doppelt so viele Zahlen haben kann.quelle