2013-12-18 4 views

Antwort

14

Es kann einen Unterschied machen. Für example:

int i = (1 << 24) + 3; 

printf("%d\n", (int)(i * 0.6)); // 10066331 
printf("%d\n", (int)(i * 0.6f)); // 10066332 

Der Grund dafür ist, dass die Berechnung für die ersten in doppelter Genauigkeit durchgeführt wird, wobei letztere in einfacher Genauigkeit. Einzelpräzision kann nicht alle Ganzzahlen größer als 1 << 24 darstellen.

Eine weitere example (mit freundlicher Genehmigung von @EricPostpischil unten in den Kommentaren):

int i = 100; 

printf("%d\n", (int)(i * 0.29)); // 28 
printf("%d\n", (int)(i * 0.29f)); // 29 

Hier ist der Grund ist, dass das Zwischenergebnis in doppelter Genauigkeit Fall leicht unter 29 fällt und so abgeschnitten wird, auf 28 nach unten

.

So würde ich vorschlagen, mit doppelter Genauigkeit erlaubt (dh den f/F Weglassen) (und dann round() Verwendung anstatt auf implizite Abschneiden unter Berufung), wenn Sie einen guten Grund, es anders zu machen.

+1

Ein kleineres Beispiel, und ein Fall, bei dem die Verwendung von "double" zu einem weniger genauen Ergebnis führt, ist, dass "int i = 100 * .29f;" 29 erzeugt, während "int i = 100 * .29;" 28 erzeugt (unter Verwendung von IEEE -754 binärer Gleitkomma). –

+0

@EricPostpischil: Oh das ist interessant. Warum die Diskrepanz dort? Weder einfach noch doppelt kann genau 0,29 darstellen; quantisiert man das eine und das andere runter? –

+0

+1, aber eine Frage: Ist nicht der Compiler _allowed_, obwohl nicht _required_, um die Berechnung in höherer Genauigkeit Mathematik zu tun? Also könnte die Antwort die gleiche sein? – chux

5

Die F ist in diesem speziellen Fall nicht erforderlich. Sie geben nur an, dass die Konstante vom Typ float statt vom Typ double ist.

1

Der erste sagt, und reduziert sich auf

i [int] = 100 [int] * 0.6 [double] 
i [int] = 100.0 [double] * 0.6 [double] 
i [int] = 60.0 [double] 

Der zweite sagt

i [int] = 100 [int] * 0.6 [float] 
i [int] = 100.0 [float] * 0.6 [float] 
i [int] = 60.0 [float] 

Beide effektiv gleich sind, wenn Sie speziell über Schwimmer vs. doppelter Genauigkeit sorgen.

1

Bei eingebetteten Systemen kann der Unterschied neben der Genauigkeit auch in der Ausführungszeit signifikant sein. f Suffix macht die Zahl eine Gleitkommakonstante im Gegensatz zu Gleitkomma-Konstante mit doppelter Genauigkeit, wie andere bereits bemerkt haben.

Wenn alle Operanden floats sind, wird die mathematische Operation mit Gleitkommazahlen einfacher Genauigkeit ausgeführt. Wenn der Prozessor eine Fließkommaeinheit mit einfacher Genauigkeit besitzt, kann er in den Berechnungen verwendet werden (abhängig von den Compileroptionen).

Wenn auf der anderen Seite any Operand ein Doppel ist, erfolgt die Berechnung in doppelter Genauigkeit. Wenn die CPU nur FPU mit einfacher Genauigkeit hat, bedeutet dies, dass die Berechnung unter Verwendung einer SW-Bibliothek erfolgt. Die Ausführungszeit des betreffenden Codes ist in diesem Fall um ein Vielfaches länger.

Beispiel für eine solche CPU ist ARM Cortex-M4F.

Ähnlich, aber nicht so radikal Unterschiedseffekt ist im Falle der keine FPU. Alle Gleitkommaoperationen verwenden die sw-Bibliothek. Doppelte Präzision braucht mehr Zeit.

+0

+1 Für eingebettete Überlegungen. In einer eingebetteten Umgebung, die ich verwendete, float und double waren das gleiche, daher nahm "double" die gleiche Zeit wie float. – chux

Verwandte Themen