Wann benutzt du float und wann double?

194

In meiner Programmiererfahrung muss ich häufig eine Entscheidung treffen, ob ich float oder double für meine reellen Zahlen verwenden soll. Manchmal gehe ich schweben, manchmal gehe ich doppelt, aber das fühlt sich wirklich subjektiver an. Wenn ich mit der Verteidigung meiner Entscheidung konfrontiert wäre, würde ich wahrscheinlich keine stichhaltigen Gründe nennen.

Wann benutzt du float und wann double? Verwenden Sie immer double, nur wenn Speicherbeschränkungen vorliegen, setzen Sie auf float? Oder verwenden Sie immer float, es sei denn, die Genauigkeitsanforderung erfordert, dass Sie double verwenden? Gibt es einige wesentliche Unterschiede hinsichtlich der rechnerischen Komplexität der Grundrechenarten zwischen float und double? Was sind die Vor- und Nachteile von Float oder Double? Und hast du schon lange Double benutzt?

Jakub Zaverka
quelle
28
In vielen Fällen möchten Sie keinen, sondern einen dezimalen Gleitkomma- oder Festkommatyp verwenden. Binäre Gleitkommatypen können die meisten Dezimalstellen nicht genau darstellen.
CodesInChaos
3
In Verbindung mit Was verursacht Gleitkomma-Rundungsfehler? . @CodesInChaos meine Antwort gibt an , um diese Feststellung zu helfen , legt nahe, gibt es keine one-size-fits-all - Lösung.
Mark Booth
Sehr gute Antwort gefunden bei: Stack Overflow
Haris
5
Was genau meinst du mit "Dezimalstellen"? Wenn Sie Werte wie 0,01 genau darstellen müssen (zum Beispiel für Geld), dann ist (binärer) Gleitkommawert nicht die Antwort. Wenn Sie nur nicht ganzzahlige Zahlen meinen, ist Fließkomma wahrscheinlich in Ordnung - aber "Dezimalzahlen" sind nicht das beste Wort, um zu beschreiben, was Sie brauchen.
Keith Thompson
1
Sie haben nicht immer eine Wahl. Beispielsweise entsprechen auf der Arduino-Plattform sowohl double als auch float float. Sie müssen eine Add-In-Bibliothek finden, um echte Doubles verarbeiten zu können.
Kiwiron

Antworten:

187

Die Standardeinstellung für einen Gleitkommatyp sollte sein double. Dies ist auch die Art , die Sie mit Gleitpunktliterale ohne Suffix erhalten oder (in C) Standardfunktionen , die auf Gleitkommazahlen arbeiten (zB exp, sinusw.).

float sollte nur verwendet werden, wenn Sie mit vielen Gleitkommazahlen arbeiten müssen (denken Sie in der Größenordnung von Tausenden oder mehr), und die Analyse des Algorithmus hat gezeigt, dass der verringerte Bereich und die verringerte Genauigkeit kein Problem darstellen.

long doublekann verwendet werden, wenn Sie mehr Reichweite oder Genauigkeit benötigen als double, und wenn dies auf Ihrer Zielplattform möglich ist.

Zusammenfassend ist festzuhalten, dass es für den Gebrauch durch die Fachleute reserviert sein sollte , floatund long doublezwar doublefür den "täglichen" Gebrauch.

Bart van Ingen Schenau
quelle
10
Ich würde Float wahrscheinlich nicht für ein paar tausend Werte in Betracht ziehen, es sei denn, es bestünde ein Leistungsproblem im Zusammenhang mit Floating-Point-Caching und Datenübertragung. Die Analyse ist normalerweise mit erheblichen Kosten verbunden, um zu zeigen, dass der Schwimmer präzise genug ist.
Patricia Shanahan
4
Wenn Sie als Ergänzung Kompatibilität mit anderen Systemen benötigen, kann es vorteilhaft sein, dieselben Datentypen zu verwenden.
zzzzBov
15
Ich würde Floats für Millionen von Zahlen verwenden, nicht für 1000er. Einige GPUs eignen sich auch besser für Floats. In diesem speziellen Fall werden Floats verwendet. Verwenden Sie ansonsten, wie Sie sagen, Doubles.
user949300
4
@PatriciaShanahan - 'Leistungsproblem im Zusammenhang mit ..' Ein gutes Beispiel ist, wenn Sie planen, SSE2 oder ähnliche Vektoranweisungen zu verwenden, können Sie 4 Operationen / Vektor im Float ausführen (vs 2 pro Doppel), was zu einer signifikanten Geschwindigkeitsverbesserung führen kann ( halb so viele Operationen und halb so viele Daten zum Lesen und Schreiben). Dies kann den Schwellenwert erheblich senken, wenn die Verwendung von Floats attraktiv wird, und es lohnt sich, die numerischen Probleme zu lösen.
Greggo
12
Ich unterstütze diese Antwort mit einem zusätzlichen Hinweis: Wenn man mit RGB-Werten für die Anzeige arbeitet, ist es akzeptabel float(und gelegentlich mit halber Genauigkeit), da weder das menschliche Auge noch die Anzeige oder das Farbsystem so viele Präzisionsteile aufweisen . Dieser Hinweis gilt beispielsweise für OpenGL usw. Dieser zusätzliche Hinweis gilt nicht für medizinische Bilder, für die strengere Genauigkeitsanforderungen gelten.
Mittwoch,
42

Es gibt selten Gründe, float anstelle von double für Code zu verwenden, der auf moderne Computer abzielt. Durch die zusätzliche Präzision wird die Wahrscheinlichkeit von Rundungsfehlern oder anderen Ungenauigkeiten, die Probleme verursachen, verringert (aber nicht beseitigt).

Die Hauptgründe für die Verwendung von float sind:

  1. Sie speichern große Zahlenfelder und müssen den Speicherverbrauch Ihres Programms reduzieren.
  2. Sie haben ein System im Visier, das Gleitkommazahlen mit doppelter Genauigkeit nicht unterstützt. Bis vor kurzem unterstützten viele Grafikkarten nur Gleitkommazahlen mit einfacher Genauigkeit. Ich bin mir sicher, dass es viele Low-Power- und Embedded-Prozessoren gibt, die ebenfalls eine eingeschränkte Gleitkomma-Unterstützung bieten.
  3. Sie zielen auf Hardware ab, bei der die einfache Genauigkeit schneller ist als die doppelte Genauigkeit, und in Ihrer Anwendung wird die Gleitkomma-Arithmetik stark genutzt. Bei modernen Intel-CPUs werden meines Erachtens alle Gleitkommaberechnungen mit doppelter Genauigkeit ausgeführt, sodass Sie hier nichts gewinnen.
  4. Sie optimieren auf niedriger Ebene, indem Sie beispielsweise spezielle CPU-Anweisungen verwenden, die mit mehreren Nummern gleichzeitig ausgeführt werden.

Im Grunde genommen ist also Double der richtige Weg, es sei denn, Sie haben Hardware-Einschränkungen oder die Analyse hat ergeben, dass das Speichern von Zahlen mit doppelter Genauigkeit erheblich zur Speichernutzung beiträgt.

user611910
quelle
2
"Moderne Computer" bedeutet Intel x86-Prozessoren. Einige der von den Ancients verwendeten Maschinen lieferten mit dem Grundschwimmer eine vollkommen ausreichende Präzision. (Der CDC 6600 verwendete ein 60-Bit-Wort, 48 Bit normalisierte Gleitkomma-Mantisse, 12 Bit Exponent. Das ist fast das, was der x86 für doppelte Präzision bietet.)
John R. Strohm
@ John.R.Strohm: einverstanden, aber C-Compiler gab es auf CDC6600 nicht. Es war Fortran IV ...
Basile Starynkevitch
Mit "modernen Computern" meine ich jeden Prozessor, der in den letzten ein oder zwei Jahrzehnten gebaut wurde, oder wirklich, seit der IEEE-Gleitkommastandard weit verbreitet war. Ich bin mir vollkommen bewusst, dass es keine x86-Architekturen gibt, und habe dies in meiner Antwort berücksichtigt. Ich erwähnte GPUs und eingebettete Prozessoren, die normalerweise nicht x86 sind.
user611910
Das stimmt aber einfach nicht. SSE2 kann 4 Floats oder 2 Double in einer Operation manipulieren, AVX kann 8 Floats oder 4 Double manipulieren, AVX-512 kann 16 Floats oder 8 Double manipulieren. Für jede Art von Hochleistungs-Computing sollte Mathematik auf Floats als doppelt so schnell wie die gleichen Operationen auf Double auf x86 angesehen werden.
Larry Gritz
1
Und es ist noch schlimmer, da Sie doppelt so viele Floats wie möglich in den Prozessor-Cache einbauen können, und die Speicherlatenz ist wahrscheinlich der Hauptengpass in vielen Programmen. Das Warmhalten einer ganzen Reihe funktionsfähiger Floats im Cache kann buchstäblich eine Größenordnung schneller sein als das Verwenden von Doubles und deren Auslagerung in den Arbeitsspeicher.
Larry Gritz
10

Verwenden Sie doublefür alle Ihre Berechnungen und temporären Variablen. Verwenden floatSie diese Option, wenn Sie eine Reihe von Zahlen verwalten müssen float[](sofern die Genauigkeit ausreicht) und Sie mit über Zehntausenden von floatZahlen arbeiten.

Viele / die meisten mathematischen Funktionen oder Operatoren konvertieren / geben zurück double, und Sie möchten die Zahlen nicht floatfür Zwischenschritte zurücksetzen.

Wenn Sie beispielsweise eine Eingabe von 100.000 Zahlen aus einer Datei oder einem Stream haben und diese sortieren müssen, geben Sie die Zahlen in a ein float[].

Fai Ng
quelle
5

Einige Plattformen (ARM Cortex-M2, Cortex-M4 usw.) unterstützen Double nicht (Dies kann immer im Referenzhandbuch zu Ihrem Prozessor nachgelesen werden. Wenn keine Warnungen oder Fehler beim Kompilieren angezeigt werden, bedeutet dies nicht, dass der Code optimal ist. double kann emuliert werden.). Aus diesem Grund müssen Sie sich möglicherweise an int oder float halten .

Wenn das nicht der Fall ist, würde ich double verwenden .

Sie können den berühmten Artikel von D. Goldberg lesen ("Was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte"). Sie sollten zweimal überlegen, bevor Sie Gleitkomma-Arithmetik verwenden. Es ist sehr wahrscheinlich, dass sie in Ihrer speziellen Situation überhaupt nicht benötigt werden.

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

staroselskii
quelle
3
Diese Frage wurde bereits vor einem Jahr ziemlich gut beantwortet ... aber auf jeden Fall würde ich sagen, wenn Sie Double auf Plattformen mit Double-Precision-FPU-Beschleunigung verwenden, sollten Sie es auf jedem anderen verwenden, auch wenn dies bedeutet Lassen Sie den Compiler es emulieren, anstatt nur eine FPU mit Gleitkommazahl zu verwenden (beachten Sie, dass FPUs auch nicht auf allen Plattformen erforderlich sind. In der Tat definiert eine Cortex-M4-Architektur sie als optionale Funktion. [War M2 ein Tippfehler?] ).
Selali Adobor
Der Schlüssel zu dieser Logik ist, während es wahr ist, sollte man der Gleitkomma-Arithmetik überdrüssig sein, und es sind viele "Macken", die definitiv nicht das Vorhandensein von FPU-Unterstützung für Doppel bedeuten, einfach Doppel anstelle von Gleitkommas zu verwenden. Floats sind im Allgemeinen schneller als Doubles und benötigen weniger Speicher (die FPU-Funktionen variieren). Das Nutzungsvolumen schließt eine vorzeitige Optimierung aus. Wie auch die Tatsache, dass Doppel für viele (vielleicht sogar die meisten) Anwendungen eindeutig übertrieben sind. Müssen die relativen Positionen und Größen der Elemente auf dieser Seite wirklich mit 13 Dezimalstellen berechnet werden ?
Selali Adobor
2
Wenn Sie einen Link zu einer Seite oder einem Dokument außerhalb der Website einfügen, kopieren Sie die relevanten Informationen oder die Zusammenfassung aus dem Dokument in Ihre Antwort. Off-Site-Links neigen dazu, im Laufe der Zeit zu verschwinden.
Adam Zuckerman
3

Bei Problemen in der Praxis ist die Stichprobenschwelle Ihrer Daten wichtig, wenn Sie diese Frage beantworten. In ähnlicher Weise ist auch das Grundrauschen wichtig. Wenn einer der beiden Werte von Ihrer Datentypauswahl überschritten wird, kann die Genauigkeit nicht verbessert werden.

Die meisten Real-World-Sampler sind auf 24-Bit-DACs beschränkt. Es wird vorgeschlagen, dass 32 Bit Genauigkeit bei Berechnungen in der realen Welt ausreichend sind, wenn der Signifikand 24 Bit Genauigkeit ist.

Doppelte Präzision kostet 2x Speicher. Daher kann die Beschränkung der Verwendung von Double-over-Floats den Speicherbedarf / die Bandbreite laufender Anwendungen drastisch verringern.

user3034617
quelle
-3

Die Wahl der zu verwendenden Variablen zwischen float und double hängt von der Genauigkeit der erforderlichen Daten ab. Wenn eine Antwort nur unwesentliche Abweichungen von der tatsächlichen Antwort haben muss, sind viele Dezimalstellen erforderlich, was die Verwendung des Doppelten vorschreibt. Der Schwebeflug schneidet einige Dezimalstellen ab, wodurch die Genauigkeit verringert wird.

David Monyancha
quelle
3
Diese Antwort fügt der Frage nichts Neues hinzu und sagt nichts über den tatsächlichen Gebrauch aus.
Martijn Pieters
-5

Normalerweise verwende ich den floatTyp, wenn ich nicht viel Präzision benötige - zum Beispiel für Geld -, was falsch ist, aber das ist, was ich falsch gewohnt bin.

Andererseits benutze ich, doublewenn ich mehr Präzision brauche, zum Beispiel für komplexe mathematische Algorithmen.

Der C99-Standard besagt Folgendes:

Es gibt drei Gleitkommatypen: float, double und long double. Der Typ double liefert mindestens so viel Präzision wie float, und der Typ long double liefert mindestens so viel Präzision wie double. Die Wertemenge vom Typ float ist eine Teilmenge der Wertemenge vom Typ double; Die Wertemenge vom Typ double ist eine Teilmenge der Wertemenge vom Typ long double.

Ich habe es nie wirklich benutzt long double, aber ich benutze C / C ++ nicht so oft. Normalerweise verwende ich dynamisch getippte Sprachen wie Python, bei denen Sie sich nicht um die Typen kümmern müssen.

Weitere Informationen zu Double vs Float finden Sie in dieser Frage bei SO .

Addison Montgomery
quelle
25
Die Verwendung von Gleitkommazahlen für ernsthafte Geldberechnungen ist wahrscheinlich ein Fehler.
Bart van Ingen Schenau
17
float ist genau der falsche Typ für Geld. Sie müssen die höchstmögliche Präzision verwenden.
ChrisF
8
@BartvanIngenSchenau Fließkomma für Geld ist normalerweise in Ordnung, binäre Fließkomma nicht. Zum Beispiel .net's Decimalist ein Gleitkommatyp und normalerweise eine gute Wahl für Geldberechnungen.
CodesInChaos
13
@ChrisF Sie brauchen keine "hohe Präzision" für Geld, Sie brauchen genaue Werte.
Sean McSomething
2
@ SeanMcSomething - Fairer Punkt. Floats sind jedoch immer noch der falsche Typ. Angesichts der in den meisten Sprachen verfügbaren Gleitkommatypen ist "hohe Präzision" erforderlich, um "genaue Werte" zu erhalten.
ChrisF