Konvertieren von float zu verdoppeln
-
07-07-2019 - |
Frage
Wie teuer ist die Umwandlung eines float
zu einem double
? Ist es wie als int
trivial Umwandlung in long
?
EDIT: Ich gehe davon aus, eine Plattform, wo, wo Schwimmer 4 Bytes und doppelt so hoch ist 8 Bytes
Lösung
Plattform Überlegungen
Dies ist abhängig von Plattform für Schwimmer Berechnung verwendet. Mit x87 FPU ist die Umwandlung frei, wie der Registerinhalt gleich ist - der einzige Preis, den Sie manchmal zahlen können, ist der Speicherverkehr, aber in vielen Fällen gibt es auch keinen Verkehr, wie Sie einfach den Wert ohne Konvertierung nutzen können. x87 ist eigentlich ein seltsames Tier in dieser Hinsicht - es ist schwer, richtig zwischen Schwimmern zu unterscheiden und verdoppelt sich darauf, wie die Anweisungen und Register, die gleichen sind, was anders ist, werden Lade- / Speicherbefehle und selbst Rechengenauigkeit Statusbits gesteuert unter Verwendung von . Misch float / double Berechnungen unter Verwendung von in unerwarteten Ergebnissen führen kann (und es gibt Compiler-Optionen Befehlszeile genaue Verhalten und Optimierungsstrategien zu steuern, weil dieser).
Wenn Sie SSE (und manchmal Visual Studio verwendet SSE Standardeinstellung), kann es anders sein, als Sie benötigen den Wert in dem FPU-Register oder etwas explizit auszuführen, um die Konvertierung zu übertragen.
Speichereinsparungen Leistung
Als Zusammenfassung und die Beantwortung auf Ihren Kommentar an anderer Stelle: Wenn Sie speichern Ergebnisse von schwebenden Berechnungen in 32b Speicher wollen, wird das Ergebnis mit gleicher Geschwindigkeit oder schneller, weil:
- Wenn Sie dies auf x87 tun, ist die Umwandlung frei - der einzige Unterschied [fstp dword] sein wird, wird statt fstp qword [] verwendet werden .
- Wenn Sie dies tun mit SSE aktiviert ist, können Sie auch einige Performance-Gewinn sehen, wie einige Schwimmer Berechnungen können mit SSE einmal die Genauigkeit der Berechnung nur insteead von Standarddoppel schweben wird durchgeführt werden.
- In allen Fällen sind der Speicherverkehr niedriger
Andere Tipps
Float zu doppelten Umrechnungen passieren kostenlos auf einigen Plattformen (PPC, x86, wenn Ihr Compiler / runtime die „Hölle verwendet mit, welche Art Sie mir gesagt zu verwenden, ich werde alles in langen Doppel ohnehin bewerten, nyah nyah "Bewertungsmodus).
Auf einem x86-Umgebung, in der Floating-Point-Auswertung tatsächlich in dem angegebenen Typ erfolgt über SSE-Register, Konvertierungen zwischen Schwimmer und Doppel sind etwa so teuer wie ein Floating-Point hinzuzufügen oder zu multiplizieren (dh unwahrscheinlich, dass eine Leistung Überlegung sein, es sei denn, Sie tun viel von ihnen).
In einer eingebetteten Umgebung, die Hardware Floating-Point fehlt, können sie etwas teuer sein.
Dies ist spezifisch für die C ++ Implementierung Sie verwenden. In C ++ ist der Standard Gleitkommatyp double . Ein Compiler sollte eine Warnung für den folgenden Code ausgeben:
float a = 3.45;
, weil der doppelte Wert 3.45 ist mit einem Schwimmer zugeordnet ist. Wenn Sie Schwimmer müssen speziell verwenden, Suffix den Wert mit f :
float a = 3.45f;
Der Punkt ist, alle Gleitkommazahlen sind standardmäßig double . Es ist sicher zu diesem Standard bleiben, wenn Sie nicht sicher über die Details der Implementierung des Compilers sind und nicht über eine beträchtliches Verständnis von Floating-Point-Berechnung. Vermeiden Sie die Besetzung.
Auch Abschnitt 4.5 von The C ++ Programming Language .
Ich kann nicht vorstellen, dass es sehr viel komplexer sein würde. Der große Unterschied zwischen int in long Umwandlung und Umwandeln Schwimmers zu verdoppeln ist, dass die Int-Typen haben zwei Komponenten (Vorzeichen und Wert), während Gleitkommazahlen hat drei Komponenten (Zeichen, Mantisse und Exponenten).
IEEE 754 mit einfacher Genauigkeit ist codierte in 32 Bit unter Verwendung von 1 Bit für das Vorzeichen, 8 Bits für den Exponenten und 23 Bits für die Mantisse. Allerdings verwendet er ein verborgenes Bit, so dass die Mantisse ist 24 Bit (p = 24), obwohl es codiert nur 23 Bits verwendet wird.
- David Goldberg, Was jeder Informatiker wissen sollten über Gleitkommatypen Arithmetic
So, zwischen float Umwandlung und Doppel wird das gleiche Vorzeichen Bit zu halten, legen Sie die letzten 23/24 Bits der Mantisse des Schwimmers auf die Mantisse des Doppel, und legen Sie die letzten 8 Bits des Exponenten des Schwimmers auf den Exponenten des Doppel.
Dieses Verhalten auch dann gewährleistet werden kann, von IEEE 754 ... Ich habe nicht geprüft, so dass ich bin mir nicht sicher.
wahrscheinlich etwas langsamer als int zu lange Umwandlung, als Speicher erforderlich ist größer und Manipulation ist komplexer. Eine gute Referenz über Speicherausrichtungsprobleme
Vielleicht Hilfe:
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
double _ftod(float fValue)
{
char czDummy[30];
printf(czDummy,"%9.5f",fValue);
double dValue = strtod(czDummy,NULL);
return dValue;
}
int main(int argc, char* argv[])
{
float fValue(250.84f);
double dValue = _ftod(fValue);//good conversion
double dValue2 = fValue;//wrong conversion
printf("%f\n",dValue);//250.840000
printf("%f\n",dValue2);//250.839996
getch();
return 0;
}