SebastianJu: round-funktion rundet falsch...

Hallo,

ich habe ein Problem mit der Funktion round().

Per Datenbankabfrage erhalte ich ein Varchar 81.225. Dieses will ich nun auf 2 Nachkommastellen runden. Also nutze ich die Funktion round(). Nur wenn ich round(zahl,2) auf diese Zahl anwende kommt am Ende 81.22 heraus. Es rundet also nicht mathematisch korrekt.

Ich habe dann probiert mit intfloat erstmal den String umzuwandeln und dann zu runden aber ohne Effekt.

Bei der Beschreibung zu round() wird ein dritter Parameter beschrieben wo man die Rundungsart angeben könne. Trotzdem soll Standard das mathematische runden sein. Aber ich kann diesen dritten Parameter nicht angeben. Weder phpEd glaubt es gibt einen dritten Parameter noch der Server der mit Fehlermeldung antwortet.

Kann mir jemand sagen wo das Problem liegt?

Grüße!
Sebastian

  1. Moin!

    ich habe ein Problem mit der Funktion round().

    Eher mit der internen binären Darstellung von Dezimalzahlen.

    Per Datenbankabfrage erhalte ich ein Varchar 81.225.

    Das ist zu diesem Zeitpunkt ein String.

    Dieses will ich nun auf 2 Nachkommastellen runden. Also nutze ich die Funktion round(). Nur wenn ich round(zahl,2) auf diese Zahl anwende kommt am Ende 81.22 heraus. Es rundet also nicht mathematisch korrekt.

    Wenn 81,225 binär nur als 81.2249999999999 dargestellt werden kann, dann ist das Rundungsverhalten erklärlich, und wäre korrekt.

    Warum lässt du die Datenbank nicht schon runden? Oder setzt Stringfunktionen zur Erzielung von "korrekter" Rundung ein. Gibt zu dem Thema auf der Handbuchseite von round() eigentlich genug Userkommentare und Lösungen.

    Bei der Beschreibung zu round() wird ein dritter Parameter beschrieben wo man die Rundungsart angeben könne. Trotzdem soll Standard das mathematische runden sein. Aber ich kann diesen dritten Parameter nicht angeben. Weder phpEd glaubt es gibt einen dritten Parameter noch der Server der mit Fehlermeldung antwortet.

    Setzt du schon PHP 5.3.0 ein? Erst damit existiert dieser Parameter. Steht so aber auch in der Doku drin - ein Blick auf den Abschnitt "Changelog" lohnt sich immer.

    - Sven Rautenberg

  2. Hallo,

    ich habe ein Problem mit der Funktion round().

    Per Datenbankabfrage erhalte ich ein Varchar 81.225.

    warum ist dies ein VARCHAR? Datenbankmanagementsysteme haben üblicherweise für die Speicherung von Zahlen geeignetere Datentypen.

    Dieses will ich nun auf 2 Nachkommastellen runden.

    Warum überlässt Du das Runden nicht Deinem Datenbankmanagementsystem?

    Kann mir jemand sagen wo das Problem liegt?

    Wahrscheinlich in unzureichender Nutzung der Eigenschaften und Fähigkeiten Deines DBMS.

    Freundliche Grüße

    Vinzenz

  3. Hallo,

    ich habe jetzt probiert mit Mysql zu runden. Statt preis gab ich:
    round(preis,2) as preisround
    aus.

    Nur rundet auch das ab obwohl ein Select auf den entsprechenden Datensatz 81.225 ergibt...

    Die Serverversion ist:

    5.0.51a-3ubuntu5.4

    Grüße!
    Sebastian

    1. Nur rundet auch das ab obwohl ein Select auf den entsprechenden Datensatz 81.225 ergibt...

      Was heisst das?

      Funktionierts oder funktionierts nicht?

      Wenns nicht funktioniert, solltest du ggf. dein Feld auf DECIMAL oder zumindest CAST() verwenden, um das ganze in einen zuverlässig verwertbaren Datentyp zu bringen.

      1. »» Nur rundet auch das ab obwohl ein Select auf den entsprechenden Datensatz 81.225 ergibt...

        Was heisst das?

        Funktionierts oder funktionierts nicht?

        Er hatte es abgerundet auf 81.22 statt 81.23...

        Aber ich glaube jetzt passt es.

        Mit
        cast(preis as decimal(10,2)) as preisround
        kommt er wirklich auf 81.23... :)

        Funktioniert jetzt also...

        Grüße!
        Sebastian

        1. Hi,

          Mit
          cast(preis as decimal(10,2)) as preisround
          kommt er wirklich auf 81.23... :)

          Funktioniert jetzt also...

          Du siehst also ein, dass du den Wert lieber gleich in einer Spalte mit vernünftig gewähltem Typ ablegen solltest?
          Gut.

          MfG ChrisB

          --
          Light travels faster than sound - that's why most people appear bright until you hear them speak.
          1. Ja klar. Ich weiß auch nicht wieso ich das als Varchar gemacht hatte. Vermutlich weil darin auch noch Texte stehen. Aber da hätte ich sicher eine bessere Lösung finden können...

            Grüße!
            Sebastian

  4. Hallo,

    Per Datenbankabfrage erhalte ich ein Varchar 81.225. Dieses will ich nun auf 2 Nachkommastellen runden. Also nutze ich die Funktion round(). Nur wenn ich round(zahl,2) auf diese Zahl anwende kommt am Ende 81.22 heraus. Es rundet also nicht mathematisch korrekt.

    Ja, das ist ein bekanntes Problem, ich habe mich darum gekümmert, dass es bei PHP 5.3 nicht mehr auftritt, siehe http://wiki.php.net/rfc/rounding und http://cvs.php.net/viewvc.cgi/php-src/ext/standard/math.c?r1=1.131.2.2.2.6.2.10&r2=1.131.2.2.2.6.2.11.

    Ich hatte hier im Forum auch mal den gleichen Algorithmus in Javascript und PHP gepostet, damit man nicht auf PHP 5.3 warten muss, um es korrekt einzusetzen:

    http://forum.de.selfhtml.org/archiv/2008/10/t178373/#m1176613

    Viele Grüße,
    Christian

    --
    Mein "Weblog" [RSS]
    Using XSLT to create JSON output (Saxon-B 9.0 for Java)
    »I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
                -- Kommentar bei TDWTF
    1. echo $begrüßung;

      Ja, das ist ein bekanntes Problem, ich habe mich darum gekümmert, dass es bei PHP 5.3 nicht mehr auftritt,

      Hmm, in PHP Version 5.2.8-pl2-gentoo tritt das Problem nicht auf, da wird aufgerundet. Vielleicht hat Gentoo den Patch schon rückwirkend aktiviert.

      echo "$verabschiedung $name";

      1. Hallo,

        Ja, das ist ein bekanntes Problem, ich habe mich darum gekümmert, dass es bei PHP 5.3 nicht mehr auftritt,

        Hmm, in PHP Version 5.2.8-pl2-gentoo tritt das Problem nicht auf, da wird aufgerundet. Vielleicht hat Gentoo den Patch schon rückwirkend aktiviert.

        Nein, in allen PHP-Versionen seit 4.nochwas gab's für das Problem einen nicht so wirklich tollen Workaround, der manchmal aktiviert war und manchmal nicht (war ganz seltsam, siehe das RFC im PHP-Wiki) - in 5.2.7 wurde das etwas vereinheitlicht und der Workaround ist jetzt immer aktiv - allerdings führt der nicht immer zu richtigen Ergebnissen.

        Viele Grüße,
        Christian

        --
        Mein "Weblog" [RSS]
        Using XSLT to create JSON output (Saxon-B 9.0 for Java)
        »I don't believe you can call yourself a web developer until you've built an app that uses hyperlinks for deletion and have all your data deleted by a search bot.«
                    -- Kommentar bei TDWTF