Double in std::string: maximale Anzahl Nachkommastellen



  • Hallo zusammen,

    zur Konvertierung von double in std::string mit einer festgelegten Anzahl Nachkommastellen habe ich folgende kleine Hilfsfunktion gebaut:

    std::string ToStringWithPrecision(double value, unsigned int precision)
    {
      std::stringstream ss;
    
      ss.setf(std::ios::fixed, std::ios::floatfield);
      ss.precision(precision);
      ss << value;
    
      return ss.str();
    }
    

    Nun werden aber auch dann Nullen als Nachkommaanteil angezeigt, wenn diese nicht benötigt werden (12 -> "12.00"). Gibt es eine Möglichkeit, die Flags so zu setzen, dass die *maximale* Zahl Nachkommastellen gesetzt wird?

    Wunsch bei zwei Nachkommastellen:
    12 -> "12"
    12.1 -> "12.1"
    12.12 -> "12.12"
    12.123 -> "12.12"
    12.1234 -> "12.12"

    Danke schonmal!
    Felix

    edit: die "Brutalo"-Variante wäre natürlich, die überflüssigen Nullen (und ggf. den Dezimaltrenner) im entstandenen String wieder zu entfernen, aber das geht hoffentlich eleganter...


  • Mod

    Bevor du es umsetzt: Hast du da dran gedacht, dass man bei deinem Plan nicht mehr unterscheiden kann, ob "12.1" nun 12.1 auf zwanzig Nachkommastellen genau oder 12.1474738438573892681874393846 auf eine Nachkommastelle genau ist? Ist das gewünscht?



  • Ja, das ist mir durchaus bewusst.

    Es geht um die Beschriftung von Achsenticks an einem xy-Graphen. Bisher waren wir so verfahren, dass wir eine feste Anzahl Nachkommastellen anzeigen (genaue Anzahl ist abhängig von der abgetragenen Einheit). Falls notwendig, wird die Zahl der Nachkommastellen erhöht, so dass sich die Ticks immer unterscheiden.

    Jetzt hat sich aber einer unserer Physiker beschwert, dass "12.000" mathematisch falsch sei, wenn "12" gemeint ist - schließlich ist der Wert exakt und nicht gerundet. Und da überlege ich jetzt, ob man das irgendwie lösen könnte.

    Ich sehe da allerdings auch noch das Problem, dass durch Fließkomma-Arithmetik durchaus Werte wie "0.10000000001" rauskommen können, wenn eigentlich "0.1" gemeint ist. Das dürfte dann wiederum nicht wie eine gerundete Zahl betrachtet werden...


  • Mod

    Ok, aber warum setzt du dann fixed? Mit setprecision bekommst du genau, was du möchtest:

    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int main() 
    {
        cout << setprecision( 4 );
        cout << 12. << endl;  // 12
        cout << 12.1 << endl;  // 12.1
        cout << 12.12 << endl;  // 12.12
        cout << 12.123 << endl;  // 12.12
        cout << 12.1234 << endl;  // 12.12
    }
    


  • Nein, setprecision ohne fixed betrachtet nicht nur die Nachkommastellen.

    #include <iostream>
    #include <iomanip>
    using namespace std;
    
    int main()
    {
        cout << setprecision( 4 );
        cout << 12. << endl;  // 12
        cout << 12.1 << endl;  // 12.1
        cout << 12.12 << endl;  // 12.12
        cout << 12.123 << endl;  // 12.12
        cout << 12.1234 << endl;  // 12.12
    
        cout << 123. << endl;  // 123
        cout << 123.1 << endl;  // 123.1
        cout << 123.12 << endl;  // 123.1
        cout << 123.123 << endl;  // 123.1
        cout << 123.1234 << endl;  // 123.1
    }
    

    Ich kläre mit den Kollegen noch, wie genau die das gerne hätten. Vielleicht wollen die am Ende doch wieder was anderes, es scheint da durchaus uterschiedliche Ansichten zu geben, wie das genau gewünscht ist.


Anmelden zum Antworten