Problem beim Runden von 1.025 auf 2 Nachkommastellen



  • hi,

    folgende funktion rundet mir eine zahl (double) auf eine anzahl von nachkommastellen.

    //---------------------------------------------------------------------------
    // LUT für 10^x (max. x = 9)
    //---------------------------------------------------------------------------
    static const int Power10_LUT[] = {        1,         10,
                                            100,       1000,
                                          10000,     100000,
                                        1000000,   10000000,
                                      100000000, 1000000000 };
    //---------------------------------------------------------------------------
    
    //---------------------------------------------------------------------------
    // Funktion rundet die angegebene Gleitkommazahl auf die nächste
    // Ganzzahl (integer) auf oder ab.
    //---------------------------------------------------------------------------
    template <> 
    inline int Round(const double Value)
    {
      return ((int) (Value < 0 ? (Value - 0.5) : (Value + 0.5)));
    }
    
    //---------------------------------------------------------------------------
    // Funktion rundet die angegebene Gleitkommazahl auf die gewünschte
    // Anzahl an Nachkommastellen.
    //---------------------------------------------------------------------------
    template <> 
    inline double Round(const double Value, const u_int Precision)
    {
      int Power10;
    
      if (Precision > 9) Power10 = pow(10.0, (double) Precision);
      else               Power10 = *(Power10_LUT + Precision);
    
      return ((double) Round(Value * Power10)) / Power10;
    }
    

    wenn ich nun folgendes aufrufe

    double zahl = 1.025
    double rnd  = Round(zahl, 2);
    

    erhalte ich 1.02 als ergebnis obwohl dieses ja 1.03 lauten müsste. der rückgabewert von Round(Value * Power10) beträgt auch korrekterweise 103. nach der division durch 100 (für 2 nachkommastellen) kommt dann aber 1.02 raus.

    wenn man statt 1.025 z.b. 1.0250000001 nimmt, kommt auch 1.03 raus.

    woran kanns liegen?



  • wenn ich das ganze mit float oder long double mache klappt es.



  • eventuell bekommst du da rundungsfehler durch pow...

    wiso machst du die sache eigentlich so kompliziert.. multipliziere doch einfach für die anzahl an stellen die du haben willst jeweils mit 10... dann addierst du 0.5 und castest nacht int ... und danach wieder anzahl der stellen mal durch 10 teilen und fertig ...



  • 1.025 kann ja nicht genau gespeichert werden, vermutlich ist für double sowas wie
    1.0249999999....
    am nähesten dran, damit zu 1.02 gerundet.



  • @windalf

    das mache ich doch auch so!

    @geo

    ja in der tat, wenn ich long double nehme, dann ist 1.025 -> 1.024999999... was dann natürlich 1.02 ergibt. wenn ich noch den suffix l anhänge (1.025l), dann funktioniert das ganze für long double.

    krieg noch mal die krise mit den gleitkomma-berechnungen.



  • Wie hat ein Buchautor aus dem Delphi-Bereich mal geschrieben: Fließkommazahlen nimmt man zum Schätzen, Ganzzahlen zum Messen...

    Indem Du den Datentyp änderst, velagerst Du das Problem nur auf andere Werte, die dann nicht korrekt abgebildet werden können.



  • das mache ich doch auch so!

    Ich meinte damit eher verwende kein pow... ist unnötig...


Anmelden zum Antworten