Was nützt das Suffix `f` beim Float-Wert?

Lesezeit: 7 Minuten

Benutzeravatar von Alex
Alex

Ich frage mich, was der Unterschied zwischen diesen beiden Variablen in C ist:

float price = 3.00;

und

float price = 3.00f;

Was ist die Verwendung von Suffix f in diesem Fall?

  • Viele Duplikate, zB “f” nach Zahl/Float in Objective-C/C

    – PaulR

    17. Februar 2011 um 8:40 Uhr


  • Ich kann die empfehlen Fließkomma-Quiz als weiterführende Lektüre.

    – Martin Scharrer

    11. April 2017 um 11:17 Uhr

  • Das f manchmal macht einen Wertunterschied in der Zuordnung.

    – chux – Wiedereinsetzung von Monica

    19. September 2021 um 8:56 Uhr

3.00 wird interpretiert als ein doubleim Gegensatz zu 3.00f was vom Compiler als a gesehen wird float.

Das f Suffix teilt dem Compiler einfach mit, was a ist float und was ist ein double.

Sehen MSDN (C++)

  • Im Beispiel von OP sind die beiden Anweisungen also gleichwertig, da das Double sowieso automatisch in einen Float gekürzt wird?

    – Lincoln Bergeson

    25. Januar 2017 um 4:51 Uhr

  • @LincolnBergeson: Im OP-Fall ja. Wenn Sie jedoch eine Gleichung hätten float price = 7.50 / 2.50; gegen float price = 7.50f / 2.50f; dann kann das Ergebnis aufgrund unterschiedlicher Auflösung abweichen. Im ersten Fall muss der Compiler die Berechnung als durchführen double Konvertieren Sie dann das Ergebnis in float. Im zweiten Fall erfolgt die Berechnung in float. Beachten Sie, dass wenn nur ein Wert ist double das ganze berechnet sich wie double. Der C-Compiler darf dies nicht wegoptimieren, da sich die Rundung unterscheiden würde. So floatvarA = floatvarB / 2.0 schlechter abschneidet als mit 2.0f.

    – Martin Scharrer

    11. April 2017 um 10:14 Uhr

Benutzeravatar von Lundin
Lundin

Zusätzlich zu dem, was bereits gesagt wurde, ist es wichtiger, den Überblick über 1.0 gegenüber 1.0f zu behalten, als viele Menschen glauben. Wenn Sie Code wie diesen schreiben:

float x;
...
float y = x * 2.0;

Dann wird x zu einem Double befördert, weil 2.0 ein Double ist. Der Compiler darf diese Beförderung nicht wegoptimieren, da dies sonst gegen den C-Standard verstoßen würde. Die Berechnung erfolgt mit doppelter Genauigkeit, und das Ergebnis wird dann implizit in einen Float gekürzt. Dies bedeutet, dass die Berechnung langsamer (aber genauer) ist, als wenn Sie 2.0f oder 2 geschrieben hätten.

Hätten Sie 2 geschrieben, wäre die Konstante vom Typ int, was zu einem Float befördert würde, und die Berechnung wäre mit “float precision” durchgeführt worden. Ein guter Compiler würde Sie vor dieser Aktion warnen.

Lesen Sie hier mehr über die “üblichen arithmetischen Umrechnungsregeln”:

http://msdn.microsoft.com/en-us/library/3t4w2bkb%28v=vs.80%29.aspx

  • Tatsächlich generiert ein Compiler, der sein Geld wert ist, eine Multiplikation mit einfacher Genauigkeit für Ihr Beispiel float y = x * 2.0;. Tatsächlich generiert ein Compiler, der sein Geld wert ist, eine Multiplikation mit einfacher Genauigkeit für float y = x * (double)0.1f;eine viel beeindruckendere Leistung (aber immer noch eine korrekte Optimierung).

    – Pascal Cuoq

    6. Juli 2013 um 16:54 Uhr


  • @PascalCuoq: Ein solcher Compiler würde gegen den C-Standard verstoßen. Du ausdrücklich ihm sagen, a zu tun double Multiplikation durch Verwendung 2.0 und nicht 2.0f. Compiler dürfen keine Optimierung verwenden, die das numerische Ergebnis verändern würde.

    – Martin Scharrer

    11. April 2017 um 10:17 Uhr

  • @MartinScharrer Es ändert nichts am numerischen Ergebnis (glauben Sie mir, ich habe das Floating-Point-Gold-Abzeichen). Ich könnte auch darauf hinweisen, dass Clang diese Optimierung anwendet, aber es gibt so viel an Clang’c-Gleitkomma, das nicht dem Standard entspricht, dass dies nichts beweisen würde.

    – Pascal Cuoq

    12. April 2017 um 6:24 Uhr


  • @MartinScharrer Die Referenz ohne Berufung auf die Behörde wurde von Figueroa geschrieben und enthält die Worte „doppelte Rundung harmlos“ im Titel, aber ich kann sie nicht in einer Version finden, die sich derzeit nicht hinter einer Paywall befindet. Es zeigt, dass (float)((double)float_x * (double)float_y) == float_x * float_y, eine Gleichheit, die der Compiler für diese Optimierung umgekehrt anwendet. Dies funktioniert, weil die Näherungen von 2 as double und float sind identisch.

    – Pascal Cuoq

    12. April 2017 um 6:30 Uhr


Benutzeravatar von Grijesh Chauhan
Grijesh Chauhan

Denn Fließkommaliterale ohne Suffixe sind Doubles, und Rundung bedeutet, dass auch kleine Literale unterschiedliche Werte annehmen können, wenn sie auf Float und Double gerundet werden. Dies kann an folgendem Beispiel beobachtet werden:

float f=0.67;
if(f == 0.67) 
  printf("yes");
else 
  printf("no");  

Dies wird ausgegeben noWeil 0.67 hat einen anderen Wert, wenn er auf Float gerundet wird, als wenn er auf Double gerundet wird. Auf der anderen Seite:

float f=0.67;
if(f == 0.67f) 
  printf("yes");
else 
  printf("no"); 

Ausgänge yes.

Das Suffix kann mit Groß- oder Kleinbuchstaben angegeben werden.

Versuchen Sie dies auch:

printf(" %u %u\n", sizeof(.67f), sizeof(.67));

Prüfen @Codepad

  • Der Vergleich von Fließkommazahlen mit == ist eine schlechte Praxis. Grund dafür sind die Fehler, die sich bei der Umwandlung von Dezimal in Binär ansammeln. Diese Fehler häufen sich, wenn Sie beginnen, Gleitkommazahlen zu manipulieren, was einen genauen Vergleich unmöglich macht. Aus diesem Grund sollten Sie niemals erwarten, dass eine Gleitkommazahl etwas Genauem entspricht.

    – Ignas2526

    31. März 2015 um 6:34 Uhr


  • @ Ignas2526 was würden Sie dann vorschlagen, wenn ich einige Zeit hineinkomme, um Floats zu vergleichen. Können Sie mir einen Hinweis geben, woher Sie weiterlesen.

    – Grijesh Chauhan

    31. März 2015 um 7:11 Uhr

  • Hier sind ein paar Seiten, die über das Problem sprechen, das ich hier erwähnt habe: docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html cygnus-software.com/papers/comparingfloats/comparingfloats.htm

    – Ignas2526

    17. April 2015 um 9:37 Uhr


  • @ Ignas2526 danke, ich werde es lesen, wenn ich etwas finde, das ich meiner Antwort hinzufügen kann, wird es aktualisiert. Dein Link wird auch für andere hilfreich sein.

    – Grijesh Chauhan

    17. April 2015 um 9:43 Uhr

3.00 ist ein Double, 3.00f ist ein Float.

Hinzufügen einiger weiterer Kombinationen von Vergleichen zwischen Float- und Double-Datentypen.

int main()
{
    // Double type constant(3.14) converts to Float type by 
    // truncating it's bits representation 
    float a = 3.14; 
    // Problem: float type 'a' promotes to double type and the value 
    // of 'a'  depends on how many bits added to represent it.
    if(a == 3.14)   
        std::cout<<"a: Equal"<<std::endl;
    else
        std::cout<<"a: Not Equal"<<std::endl; 

    float b = 3.14f; // No type conversion
    if(b == 3.14)    // Problem: Float to Double conversion
        std::cout<<"b: Equal"<<std::endl;
    else
        std::cout<<"b: Not Equal"<<std::endl;

    float c = 3.14; // Double to Float conversion (OK even though is not a good practice )
    if(c == 3.14f)  // No type conversion 
        std::cout<<"c: Equal"<<std::endl;  // OK
    else
        std::cout<<"c: Not Equal"<<std::endl;

    float d = 3.14f;
    if(d == 3.14f)
        std::cout<<"d: Equal"<<std::endl; // OK
    else
        std::cout<<"d: Not Equal"<<std::endl;

    return 0;
}    

Ausgabe:

 a: Not Equal
 b: Not Equal
 c: Equal
 d: Equal

Benutzeravatar von unwind
entspannen

Das liegt daran, dass der Standardtyp eines numerischen Fließkomma-Literals – die Zeichen 3,00 – Double und nicht Float sind. Um diese Kompilierung durchzuführen, müssen Sie das Suffix f (oder F) hinzufügen.

Benutzeravatar von Frederik Slijkerman
Frederik Schlijkerman

Oft ist der Unterschied nicht wichtig, da der Compiler die Double-Konstante sowieso in einen Float umwandelt. Bedenken Sie jedoch Folgendes:

template<class T> T min(T a, T b)
{
  return (a < b) ? a : b;
}

float x = min(3.0f, 2.0f); // will compile
x = min(3.0f, 2);   // compiler cannot deduce T type
x = min(3.0f, 2.0); // compiler cannot deduce T type

  • Ihre Antwort erklärt den Unterschied zwischen 3,00 und 3,00f jedoch nicht eindeutig …

    – James

    17. Februar 2011 um 8:33 Uhr

  • Genau … Sie können einige Informationen hinzufügen, aber Sie beantworten die Frage nicht …

    – James

    17. Februar 2011 um 8:58 Uhr

  • Wenn Sie versuchen, eine Double-Konstante in einem Float zu speichern, erhalten Sie eine implizite Verschlechterung von Double zu Float. Aber wenn es um Ausdrücke geht, kann der Compiler Double-Konstanten nicht in Float umwandeln, ohne den C/C++-Standard zu verletzen. Steht eine Double-Konstante im selben Ausdruck wie ein Float, dann verlangen die “üblichen arithmetischen Konvertierungsregeln” von C/C++, dass das Float implizit zu einem Double hochgestuft wird.

    – Ludin

    17. Februar 2011 um 9:42 Uhr


  • Warum antworten Sie auch mit C++, wenn das OP in C schreibt? Ihr Beispiel ist in C irrelevant, da C nicht die gleiche strenge Typprüfung wie C++ hat.

    – Ludin

    17. Februar 2011 um 9:43 Uhr

1418240cookie-checkWas nützt das Suffix `f` beim Float-Wert?

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

Privacy policy