Was sind die Vor- und Nachteile der Verwendung eines in C ++ anstelle des anderen?
Was sind die Vor- und Nachteile der Verwendung eines in C ++ anstelle des anderen?
Antworten:
Wenn Sie die wahre Antwort wissen möchten, sollten Sie lesen, was jeder Informatiker über Gleitkomma-Arithmetik wissen sollte .
Kurz gesagt, obwohl double
eine höhere Genauigkeit in der Darstellung möglich ist, würde es bei bestimmten Berechnungen zu größeren Fehlern kommen . Die "richtige" Wahl ist: Verwenden Sie so viel Präzision wie Sie brauchen, aber nicht mehr und wählen Sie den richtigen Algorithmus .
Viele Compiler führen ohnehin erweiterte Gleitkomma-Berechnungen im "nicht strengen" Modus durch (dh sie verwenden einen breiteren Gleitkommatyp, der in der Hardware verfügbar ist, z. B. 80-Bit- und 128-Bit-Gleitkomma). Dies sollte ebenfalls berücksichtigt werden. In der Praxis kann man kaum einen Unterschied in der Geschwindigkeit feststellen - sie sind sowieso einheimisch in der Hardware.
double
sie einfach - dies ist in den meisten Fällen sicherer.
Verwenden Sie double, es sei denn, Sie haben einen bestimmten Grund, etwas anderes zu tun.
Es ist vielleicht überraschend, dass Double und nicht Float der "normale" Gleitkommatyp in C (und C ++) ist. Die Standard-Mathematikfunktionen wie sin und log verwenden doppelte Argumente und geben doppelte zurück. Ein normales Gleitkomma-Literal, wie wenn Sie 3.14 in Ihr Programm schreiben , hat den Typ double. Nicht schweben.
Auf typischen modernen Computern können Doubles genauso schnell wie Floats oder sogar noch schneller sein, sodass die Leistung selbst bei großen Berechnungen normalerweise kein zu berücksichtigender Faktor ist. (Und das müssten umfangreiche Berechnungen sein, sonst sollte Ihnen die Leistung nicht einmal in den Sinn kommen. Mein neuer i7-Desktop-Computer kann sechs Milliarden Multiplikationen von Doppel in einer Sekunde ausführen.)
Diese Frage ist nicht zu beantworten, da die Frage keinen Kontext hat. Hier sind einige Dinge, die die Auswahl beeinflussen können:
Compiler-Implementierung von Floats, Doubles und Long Doubles. Der C ++ - Standard besagt:
Es gibt drei Gleitkommatypen: float, double und long double. Der Typ double bietet mindestens so viel Präzision wie float, und der Typ long double bietet mindestens so viel Präzision wie double.
Alle drei können also im Speicher dieselbe Größe haben.
Anwesenheit einer FPU. Nicht alle CPUs haben FPUs und manchmal werden die Gleitkommatypen emuliert und manchmal werden die Gleitkommatypen einfach nicht unterstützt.
FPU-Architektur. Die FPU des IA32 ist intern 80 Bit - 32-Bit- und 64-Bit-Floats werden beim Laden auf 80 Bit erweitert und beim Speichern reduziert. Es gibt auch SIMD, das vier 32-Bit-Floats oder zwei 64-Bit-Floats parallel ausführen kann. Die Verwendung von SIMD ist im Standard nicht definiert, daher wäre ein Compiler erforderlich, der komplexere Analysen durchführt, um festzustellen, ob SIMD verwendet werden kann, oder die Verwendung spezieller Funktionen (Bibliotheken oder Intrinsics). Das Ergebnis des internen 80-Bit-Formats ist, dass Sie leicht unterschiedliche Ergebnisse erzielen können, je nachdem, wie oft die Daten im RAM gespeichert werden (wodurch die Genauigkeit verloren geht). Aus diesem Grund optimieren Compiler Gleitkomma-Code nicht besonders gut.
Speicherbandbreite. Wenn ein Double mehr Speicher benötigt als ein Float, dauert das Lesen der Daten länger. Das ist die naive Antwort. Bei einem modernen IA32 hängt alles davon ab, woher die Daten stammen. Wenn es sich im L1-Cache befindet, ist die Last vernachlässigbar, vorausgesetzt, die Daten stammen aus einer einzelnen Cache-Zeile. Wenn es mehr als eine Cache-Zeile umfasst, entsteht ein geringer Overhead. Wenn es von L2 ist, dauert es eine Weile länger, wenn es im RAM ist, dann ist es noch länger und schließlich, wenn es auf der Festplatte ist, ist es eine große Zeit. Die Wahl von float oder double ist daher weniger wichtig als die Art und Weise, wie die Daten verwendet werden. Wenn Sie eine kleine Berechnung für viele sequentielle Daten durchführen möchten, ist ein kleiner Datentyp vorzuziehen. Wenn Sie viel mit einem kleinen Datensatz rechnen, können Sie größere Datentypen mit erheblichen Auswirkungen verwenden. Wenn du' Wenn Sie sehr zufällig auf die Daten zugreifen, ist die Wahl der Datengröße unwichtig - Daten werden in Seiten / Cache-Zeilen geladen. Selbst wenn Sie nur ein Byte aus dem RAM benötigen, können 32 Bytes übertragen werden (dies hängt stark von der Architektur des Systems ab). Darüber hinaus könnte die CPU / FPU superskalar sein (auch bekannt als Pipeline). Obwohl ein Ladevorgang mehrere Zyklen dauern kann, kann die CPU / FPU damit beschäftigt sein, etwas anderes zu tun (z. B. eine Multiplikation), das die Ladezeit bis zu einem gewissen Grad verbirgt.
Der Standard erzwingt kein bestimmtes Format für Gleitkommawerte.
Wenn Sie eine Spezifikation haben, führt Sie dies zur optimalen Auswahl. Ansonsten liegt es an der Erfahrung, was zu verwenden ist.
Double ist genauer, wird jedoch auf 8 Bytes codiert. float ist nur 4 Bytes, also weniger Platz und weniger Präzision.
Sie sollten sehr vorsichtig sein, wenn Sie Double und Float in Ihrer Anwendung haben. Aufgrund dessen hatte ich in der Vergangenheit einen Fehler. Ein Teil des Codes verwendete float, während der Rest des Codes double verwendete. Das Kopieren von double in float und dann float in double kann zu Präzisionsfehlern führen, die große Auswirkungen haben können. In meinem Fall war es eine Chemiefabrik ... hoffentlich hatte es keine dramatischen Konsequenzen :)
Ich denke, dass die Ariane 6-Rakete vor ein paar Jahren wegen dieser Art von Fehler explodiert ist !!!
Überlegen Sie genau, welcher Typ für eine Variable verwendet werden soll
Dies hängt davon ab, wie der Compiler double implementiert. Es ist legal, dass Double und Float vom gleichen Typ sind (und dies ist auf einigen Systemen der Fall).
Wenn sie jedoch tatsächlich unterschiedlich sind, ist das Hauptproblem die Präzision. Ein Doppel hat aufgrund seines Größenunterschieds eine viel höhere Präzision. Wenn die von Ihnen verwendeten Zahlen normalerweise den Wert eines Floats überschreiten, verwenden Sie ein Double.
Mehrere andere Personen haben Leistungsprobleme erwähnt. Das wäre genau das Letzte auf meiner Liste der Überlegungen. Korrektheit sollte Ihre erste Überlegung sein.
Verwenden Sie die erforderliche Präzision, um die entsprechenden Ergebnisse zu erzielen . Wenn Sie dann feststellen, dass Ihr Code nicht so gut funktioniert, wie Sie möchten (Sie haben die Profilerstellung korrekt verwendet?), Sehen Sie sich Folgendes an:
Ich denke, unabhängig von den Unterschieden (die, wie alle betonen, Floats weniger Platz beanspruchen und im Allgemeinen schneller sind) ... hat jemand jemals Leistungsprobleme mit Double? Ich sage Double verwenden ... und wenn Sie später entscheiden "Wow, das ist wirklich langsam" ... finden Sie Ihren Leistungsengpass (was wahrscheinlich nicht die Tatsache ist, dass Sie Double verwendet haben). DANN, wenn es Ihnen immer noch zu langsam ist, sehen Sie, wo Sie etwas Präzision opfern und float verwenden können.
Der Hauptunterschied zwischen Float und Double ist die Präzision. Wikipedia bietet weitere Informationen zu einfacher Genauigkeit (float) und doppelter Genauigkeit .
Es hängt stark von der CPU ab. Die offensichtlichsten Kompromisse bestehen zwischen Präzision und Speicher. Bei GB RAM ist der Speicher kein großes Problem, daher ist es im Allgemeinen besser, double
s zu verwenden .
Die Leistung hängt stark von der CPU ab. float
s erzielt normalerweise eine bessere Leistung als double
s auf einem 32-Bit-Computer. Bei 64 Bit sind double
s manchmal schneller, da es (normalerweise) die native Größe ist. Viel wichtiger als die Auswahl der Datentypen ist jedoch, ob Sie die SIMD-Anweisungen auf Ihrem Prozessor nutzen können oder nicht.
double hat eine höhere Präzision, während Floats weniger Speicher beanspruchen und schneller sind. Im Allgemeinen sollten Sie float verwenden, es sei denn, Sie haben einen Fall, in dem es nicht genau genug ist.