Was ist der Unterschied zwischen Float und Double?

Lesezeit: 7 Minuten

Was ist der Unterschied zwischen Float und Double
VaioIsBorn

Ich habe über den Unterschied zwischen doppelter und einfacher Genauigkeit gelesen. In den meisten Fällen jedoch float und double scheinen austauschbar zu sein, dh die Verwendung des einen oder anderen scheint die Ergebnisse nicht zu beeinflussen. Ist dies wirklich der Fall? Wann sind Floats und Doubles austauschbar? Was sind die Unterschiede zwischen ihnen?

1647091816 777 Was ist der Unterschied zwischen Float und Double
kennytm

Riesiger Unterschied.

Wie der Name schon sagt, a double hat die doppelte Genauigkeit von float[1]. Im Allgemeinen a double hat eine Genauigkeit von 15 Dezimalstellen, während float hat 7.

So wird die Anzahl der Ziffern berechnet:

double hat 52 Mantissenbits + 1 verborgenes Bit: log(253)÷log(10) = 15,95 Stellen

float hat 23 Mantissenbits + 1 verborgenes Bit: log(224)÷log(10) = 7,22 Stellen

Dieser Genauigkeitsverlust könnte dazu führen, dass größere Abschneidefehler akkumuliert werden, 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

Außerdem ist der maximale Wert von Float ungefähr 3e38aber das Doppelte ist ungefähr 1.7e308also mit float kann viel leichter auf “unendlich” (dh eine spezielle Fließkommazahl) treffen als double für etwas Einfaches, zB Berechnung der Fakultät von 60.

Während des Testens enthalten möglicherweise einige Testfälle diese riesigen Zahlen, die dazu führen können, dass Ihre Programme fehlschlagen, wenn Sie Gleitkommazahlen verwenden.


Natürlich manchmal sogar double ist nicht genau genug, daher haben wir manchmal long double[1] (das obige Beispiel ergibt 9.000000000000000066 auf dem Mac), aber alle Fließkommatypen leiden darunter Rundungsfehleralso wenn Genauigkeit sehr wichtig ist (zB Geldverarbeitung) sollten Sie verwenden int oder eine Bruchklasse.


Außerdem nicht verwenden += viele Fließkommazahlen zu summieren, da sich die Fehler schnell anhäufen. Wenn Sie Python verwenden, verwenden Sie fsum. Versuchen Sie andernfalls, die zu implementieren Kahan-Summierungsalgorithmus.


[1]: Die C- und C++-Standards spezifizieren nicht die Darstellung von float, double und long double. Es ist möglich, dass alle drei als IEEE-Double-Precision implementiert sind. Dennoch für die meisten Architekturen (gcc, MSVC; x86, x64, ARM) float ist in der Tat eine IEEE-Gleitkommazahl mit einfacher Genauigkeit (binary32) und double ist eine IEEE-Gleitkommazahl mit doppelter Genauigkeit (binary64).

  • Der übliche Rat für die Summierung ist, Ihre Gleitkommazahlen vor der Summierung nach Größe (kleinste zuerst) zu sortieren.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    6. August 2010 um 9:49 Uhr

  • Beachten Sie, dass, während C/C++ Float und Double fast immer IEEE Single und Double Precision sind, bzw. C/C++ Long Double viel variabler ist, abhängig von Ihrer CPU, Ihrem Compiler und Ihrem Betriebssystem. Manchmal ist es dasselbe wie doppelt, manchmal ist es ein systemspezifisches erweitertes Format, manchmal ist es IEEE Quad-Präzision.

    – Plugwash

    8. Februar 2019 um 5:27 Uhr

  • @R..GitHubSTOPHELPINGICE: warum? Könntest du erklären?

    – InQusitive

    2. Januar 2020 um 7:27 Uhr

  • @InQusitive: Stellen Sie sich zum Beispiel ein Array vor, das aus dem Wert 2 ^ 24 besteht, gefolgt von 2 ^ 24 Wiederholungen des Werts 1. Das Summieren in der Reihenfolge ergibt 2 ^ 24. Umkehren ergibt 2^25. Natürlich können Sie Beispiele machen (z. B. 2 ^ 25 Wiederholungen von 1), bei denen jede Reihenfolge mit einem einzelnen Akkumulator katastrophal falsch ist, aber die kleinste Größe zuerst ist die beste unter solchen. Um es besser zu machen, braucht man eine Art Baum.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    2. Januar 2020 um 15:18 Uhr

  • @R..GitHubSTOPHELPINGICE: Das Summieren ist noch schwieriger, wenn das Array sowohl positive als auch negative Zahlen enthält.

    – chqrlie

    7. September 2020 um 8:59 Uhr

Was ist der Unterschied zwischen Float und Double
Gregor Pakosz

Folgendes sagen die Standards C99 (ISO-IEC 9899 6.2.5 §10) oder C++2003 (ISO-IEC 14882-2003 3.1.9 §8) aus:

Es gibt drei Fließkommatypen: float, doubleund long double. Der Typ double bietet mindestens so viel Präzision wie floatund der Typ long double bietet mindestens so viel Präzision wie double. Der Satz von Werten des Typs float ist eine Teilmenge der Menge von Werten des Typs double; die Wertemenge des Typs double ist eine Teilmenge der Menge von Werten des Typs long double.

Der C++-Standard fügt hinzu:

Die Wertdarstellung von Fließkommatypen ist implementierungsdefiniert.

Ich würde vorschlagen, einen Blick auf das Ausgezeichnete zu werfen Was jeder Informatiker über Gleitkommaarithmetik wissen sollte das den IEEE-Gleitkommastandard ausführlich behandelt. Sie lernen die Darstellungsdetails kennen und erkennen, dass es einen Kompromiss zwischen Größe und Genauigkeit gibt. Die Genauigkeit der Fließkommadarstellung nimmt mit abnehmender Größe zu, daher sind Fließkommazahlen zwischen -1 und 1 die mit der größten Genauigkeit.

Gegeben eine quadratische Gleichung: x2 − 4.0000000 x + 3.9999999 = 0, die genauen Wurzeln zu 10 signifikanten Stellen sind, R1 = 2,000316228 und R2 = 1,999683772.

Verwenden float und doublekönnen wir ein Testprogramm schreiben:

#include <stdio.h>
#include <math.h>

void dbl_solve(double a, double b, double c)
{
    double d = b*b - 4.0*a*c;
    double sd = sqrt(d);
    double r1 = (-b + sd) / (2.0*a);
    double r2 = (-b - sd) / (2.0*a);
    printf("%.5f\t%.5f\n", r1, r2);
}

void flt_solve(float a, float b, float c)
{
    float d = b*b - 4.0f*a*c;
    float sd = sqrtf(d);
    float r1 = (-b + sd) / (2.0f*a);
    float r2 = (-b - sd) / (2.0f*a);
    printf("%.5f\t%.5f\n", r1, r2);
}   

int main(void)
{
    float fa = 1.0f;
    float fb = -4.0000000f;
    float fc = 3.9999999f;
    double da = 1.0;
    double db = -4.0000000;
    double dc = 3.9999999;
    flt_solve(fa, fb, fc);
    dbl_solve(da, db, dc);
    return 0;
}  

Das Ausführen des Programms gibt mir:

2.00000 2.00000
2.00032 1.99968

Beachten Sie, dass die Zahlen nicht groß sind, aber Sie erhalten immer noch Aufhebungseffekte float.

(Tatsächlich ist das Obige nicht der beste Weg, um quadratische Gleichungen mit Gleitkommazahlen einfacher oder doppelter Genauigkeit zu lösen, aber die Antwort bleibt unverändert, selbst wenn man a verwendet stabilere Methode.)

  • Ein Double ist 64 und eine einfache Genauigkeit (Float) ist 32 Bit.
  • Das Double hat eine größere Mantisse (die ganzzahligen Bits der reellen Zahl).
  • Jegliche Ungenauigkeiten werden im Doppel kleiner sein.

Was ist der Unterschied zwischen Float und Double
Elliskop Fang

Ich bin gerade auf einen Fehler gestoßen, für den ich ewig gebraucht habe, um ihn herauszufinden, und der Ihnen möglicherweise ein gutes Beispiel für Float-Präzision geben kann.

#include <iostream>
#include <iomanip>

int main(){
  for(float t=0;t<1;t+=0.01){
     std::cout << std::fixed << std::setprecision(6) << t << std::endl;
  }
}

Die Ausgabe ist

0.000000
0.010000
0.020000
0.030000
0.040000
0.050000
0.060000
0.070000
0.080000
0.090000
0.100000
0.110000
0.120000
0.130000
0.140000
0.150000
0.160000
0.170000
0.180000
0.190000
0.200000
0.210000
0.220000
0.230000
0.240000
0.250000
0.260000
0.270000
0.280000
0.290000
0.300000
0.310000
0.320000
0.330000
0.340000
0.350000
0.360000
0.370000
0.380000
0.390000
0.400000
0.410000
0.420000
0.430000
0.440000
0.450000
0.460000
0.470000
0.480000
0.490000
0.500000
0.510000
0.520000
0.530000
0.540000
0.550000
0.560000
0.570000
0.580000
0.590000
0.600000
0.610000
0.620000
0.630000
0.640000
0.650000
0.660000
0.670000
0.680000
0.690000
0.700000
0.710000
0.720000
0.730000
0.740000
0.750000
0.760000
0.770000
0.780000
0.790000
0.800000
0.810000
0.820000
0.830000
0.839999
0.849999
0.859999
0.869999
0.879999
0.889999
0.899999
0.909999
0.919999
0.929999
0.939999
0.949999
0.959999
0.969999
0.979999
0.989999
0.999999

Wie man sieht, geht die Genauigkeit nach 0,83 deutlich zurück.

Allerdings, wenn ich aufstelle t als doppelt, wird ein solches Problem nicht auftreten.

Ich brauchte fünf Stunden, um diesen kleinen Fehler zu erkennen, der mein Programm ruinierte.

  • Nur um sicherzugehen: Die Lösung Ihres Problems sollte darin bestehen, vorzugsweise ein int zu verwenden? Wenn Sie 100 Mal iterieren möchten, sollten Sie mit einem int rechnen, anstatt ein Double zu verwenden

    – BlueTrin

    19. September 2016 um 12:07 Uhr

  • Verwenden double ist hier keine gute Lösung. Sie verwenden int zu zählen und eine interne Multiplikation durchzuführen, um Ihren Gleitkommawert zu erhalten.

    – Richard

    24. September 2017 um 23:10 Uhr

1647091818 26 Was ist der Unterschied zwischen Float und Double
Nr

Die Größe der Zahlen, die in die Gleitkommaberechnungen einbezogen werden, ist nicht das Wichtigste. 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 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.

Die Tests verwenden möglicherweise speziell Zahlen, die diese Art von Fehler verursachen würden, und haben daher getestet, ob Sie den richtigen Typ in Ihrem Code verwendet haben.

  • Nur um sicherzugehen: Die Lösung Ihres Problems sollte darin bestehen, vorzugsweise ein int zu verwenden? Wenn Sie 100 Mal iterieren möchten, sollten Sie mit einem int rechnen, anstatt ein Double zu verwenden

    – BlueTrin

    19. September 2016 um 12:07 Uhr

  • Verwenden double ist hier keine gute Lösung. Sie verwenden int zu zählen und eine interne Multiplikation durchzuführen, um Ihren Gleitkommawert zu erhalten.

    – Richard

    24. September 2017 um 23:10 Uhr

1647091819 340 Was ist der Unterschied zwischen Float und Double
Peter Mortensen

Typ Float, 32 Bit lang, 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.

Type long double ist nominell 80 Bit, obwohl eine gegebene Compiler/OS-Paarung ihn zu Ausrichtungszwecken als 12–16 Byte speichern kann. Das lange Double hat einen Exponenten, der einfach lächerlich groß ist und eine Genauigkeit von 19 Stellen haben sollte. Microsoft begrenzt in seiner unendlichen Weisheit Long Double auf 8 Bytes, genau wie Plain Double.

Verwenden Sie im Allgemeinen einfach den Typ double, wenn Sie einen Gleitkommawert / eine Gleitkommavariable benötigen. Literale Gleitkommawerte, die in Ausdrücken verwendet werden, werden standardmäßig als Doubles behandelt, und die meisten mathematischen Funktionen, die Gleitkommawerte zurückgeben, geben Doubles zurück. Sie ersparen sich viele Kopfschmerzen und Tippfehler, wenn Sie einfach doppelt verwenden.

993730cookie-checkWas ist der Unterschied zwischen Float und Double?

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

Privacy policy