Suffix verwenden



  • Guten Abend,

    und zwar habe ich Probleme zu unterscheiden wann einem Wert ein Suffix angehangen wird und wann nicht. 😕

    float test = 0.53;
    

    Bis jetzt hab ich das immer so verstanden: Durch "float" wird im Speicher Platz freigegeben für eine Zahl vom Typ float. Dann wird dieser Speicher mit dem Wert 0.53 beschrieben. Nun hab ich in meinem Buch "Der C++ Pragrammierer" das Thema mit Suffixen gehabt und nicht so recht verstanden wann und wozu das dient. Ich habe danach weitergelesen, allerdings wurde auf den nächsten Seiten nicht noch einmal darauf eingegangen. Hier im Forum gab es schon einmal einen Beitrag dazu, allerdings bin ich daraus auch nicht schlauer geworden. Ich habe es so verstanden, dass der Compiler die Zahl als double liest und interpretiert, allerdings verstehe ich nicht warum ich dann float angeben muss wenn er eh einen anderen Datentyp daraus macht. Ich vermute ich habe hier einen totalen Denkfehler. Wie funktioniert das mit den Suffixen? Wann werden sie benutzt und wann nicht? 😕



  • Es geht um die Präzision bei Dezimalkonstanten. Solche ohne f-Suffix interpretiert der Compiler als vom Typ double. Mit f-Suffix wird die Interpretation als Typ float erzwungen. Code zum Testen:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main  ()
    {
    // mit und ohne f-Suffix testen: 0.3, 0.5, 0.7, 1.0
    #define n 0.53
    #define nf 0.53f
    // und anstatt Typ float auch mal double verwenden:
    #define flp_t float
    #define flp_s "float"
    
        flp_t  a = n, b = nf;
    
        printf("%s a=%f\n", flp_s, a);
        printf("%s b=%f\n", flp_s, b);
        if (a == n)
            printf("a: true\n");
        else
            printf("a: false\n");
        if (a == nf)
            printf("a: true\n");
        else
            printf("a: false\n");
        if (b == n)
            printf("b: true\n");
        else
            printf("b: false\n");
        if (b == nf)
            printf("b: true\n");
        else
            printf("b: false\n");
        return 0;
    }
    


  • ok, dann hätte ich noch 2 Fragen.

    1. Wenn ein Ergebnis einer Berechnung in einer Variable vom Typ float gespeichert wird, dann ist das Ergebnis auch wirklich ein float oder? Das Problem entsteht ja nur beim direkten festlegen von Literalen oder?

    2. Es macht also eigentlich immer Sinn den Suffix anzugeben wenn man präzise mit Dezimalzahlen arbeiten will und die zu berechnenden Zahlen dabei direkt als Literal angibt? Oder macht es gar immer Sinn den Suffix anzugeben bei float und double Lietralen?


  • Mod

    Zhavok schrieb:

    1. Wenn ein Ergebnis einer Berechnung in einer Variable vom Typ float gespeichert wird, dann ist das Ergebnis auch wirklich ein float oder? Das Problem entsteht ja nur beim direkten festlegen von Literalen oder?

    Eine Variable eines bestimtmen Typs kann nur Werte dieses Typs enthalten. Das gilt für float und für alle anderen Typen.

    Ich weiß nicht, von welchem Problem du redest.

    2. Es macht also eigentlich immer Sinn den Suffix anzugeben wenn man präzise mit Dezimalzahlen arbeiten will und die zu berechnenden Zahlen dabei direkt als Literal angibt? Oder macht es gar immer Sinn den Suffix anzugeben bei float und double Lietralen?

    Eigentlich brauchst du fast nie Suffixe. Es gibt ein paar Beispielszenarien mit Templates und/oder Überladung, wo es wichtig sein kann, dass ein Literal einen bestimmten Typ hat.

    Du hast die völlig falsche Botschaft mitgenommen, wenn du denkst, du solltest viele Suffixe benutzen.



  • Ah ok. Ich habe mal ein Programm oben etwas simples abgeleitet.

    float test = 5.2;
    
    if (test == 5.2f)   //funktioniert nicht ohne Suffix
    {std::cout << "Geht";}
    else
    {std::cout << "Geht nicht";}
    
    getchar();
    

    Hier ist es ja sozusagen schon von Nöten, dass der Suffix dran hängt. Das Problem im Beispiel ist, dass der 5.2 bei der Abfrage ja kein Datentyp direkt zugewiesen wird. Dann wird aus der 5.2 ein double und daraus folgt, dass aufgrund der Genauigkeit beide Zahlen nicht genau gleich sind und "Geht nicht" ausgegeben wird. Somit muss man dort den Suffix anhängen wie im Beispiel.

    Habe ich das jetzt richtig verstanden? 🙂



  • Fließkommazahlen (float, double usw.) sollte man nicht auf Gleichheit (==) testen!



  • Und den Unterschied siehst du noch hier:

    auto f = 0.1f;
    auto d = 0.1;
    

    Im ersten Fall wird eine Float-Variable erzeugt, im zweiten Fall eine double-Variable.

    Es kann z.B. hier Unterschiede geben:

    int i = (1<<31) - 1;
    

    Das ergibt bei mir die Warnung warning: overflow in expression; result is 2147483647 with type 'int' [-Winteger-overflow] , während folgendes nicht warnt:

    int i = (1u<<31) - 1u;
    

    Wo ich das suffix öfter mal nutze: wenn man viele Overloads einer Funktion hat, die dann entweder float,float oder double,double oder noch mehr Varianten hat und man z.B. eine Variable und eine Zahl übergeben will.
    also

    int foo(float, float){return 1;}
    int foo(double, double){return 2;}
    
    ...
    
    float f = 42;
    cout << foo(f, 1.23) << "\n"; // geht nicht
    cout << foo(f, 1.23f) << "\n"; // geht!
    

  • Mod

    Zhavok schrieb:

    Habe ich das jetzt richtig verstanden? 🙂

    Was du zeigst, ist korrekt, aber halt recht unrealistisch. Wann hat man solch einen Fall schon jemals, dass man eine float-Variable mit einem festen Dezimalwert auf absolute Gleichheit testen möchte? Und wann man den Fall hat, dann siehe Bellis Kommentar dazu.

    wob zeigt ein Beispiel zu dem was ich in meiner vorherigen Antwort nur mit Worten beschrieben habe. Solche und ähnliche Fälle sind es, wo man in der Praxis auch mal Literale mit expliziter Typangabe benötigt. Sehr häufig ist dies jedoch nicht. Ein praktisches Beispiel, dem viele C++-Programmierer mal begegnet sein dürften, sind ein paar alle aus cmath aus der Zeit vor 2011, wo scheinbar harmlos aussehende Funktionsaufrufe uneindeutig waren:
    https://ideone.com/v4uETz (man beachte, dass ich da mit Absicht eine alte C++-Version wählen musste, in neueren Versionen ist die Problematik gelöst)



  • ok, vielen dank 👍 👍 👍

    zu dem Beispiel mit den Overloads kann ich momentan noch nicht viel sagen. So einen Fall hatte ich noch nicht. Da muss ich erst noch ein wenig weiter sein mit meinem Buch 😃 👍


Anmelden zum Antworten