Mathematisch RICHTIG runden???

  • VB.NET

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von gonzo16.

    Mathematisch RICHTIG runden???

    Hallo,

    gibt es in VB wirklich keine Funktion, die mathematisch richtig rundet? Ich kann das einfach nicht glauben. Die Funktionen Int, Fix sowie Math.Floor und Math.Ceiling runden immer auf oder ab. Auch die "richtige" Rundungsfunktion Math.Round rundet mathematisch nicht richtig, da sie bei einem Nachkommateil von exakt 0,5 zur nächsten geraden!! Zahl rundet :cursing:. So ein Schwachsinn!!!

    Gibt es noch andere Rundungsfunktionen oder wie macht ihr das, wenn ihr einen Wertmathematisch richtig runden wollt?

    Der etwas verwirrte
    Gonzo16

    gonzo16 schrieb:

    Auch die "richtige" Rundungsfunktion Math.Round rundet mathematisch nicht richtig, da sie bei einem Nachkommateil von exakt 0,5 zur nächsten geraden!! Zahl rundet . So ein Schwachsinn!!!

    Wo liegt hier der Schwachsinn? Das ist doch korrektes kaufmännisches Runden.

    Such dir eine Funktion aus

    VB.NET-Quellcode

    1. Dim i As Double
    2. i = 3.3
    3. 'Schneidet die Nachkommastellen ab
    4. '("wird Richtung Null auf die nächste Ganzzahl gerundet")
    5. 'wichtig bei Rundungen von negativen Zahlen
    6. MessageBox.Show("Math.Truncate: " & Math.Truncate(i))
    7. 'die nächstkleinere Ganzzahl
    8. MessageBox.Show("Math.Floor: " & Math.Floor(i))
    9. 'die nächstgrössere Ganzzahl
    10. MessageBox.Show("Math.ceiling: " & Math.Ceiling(i))
    11. 'rundet mathematisch richtig
    12. '(rundet bis 3.49 ab, ab 3.5 auf)
    13. MessageBox.Show("Math.Round: " & Math.Round(i))
    Also, soweit ich mich an die Schulmathematik erinnere, wird bei einem Nachkommateil von 0,5 auf die nächste Zahl aufgerundet. Also 1,5 wird zu 2 gerundet und 2,5 wird zu 3 gerundet.

    Math.Round rundet aber immer zur nächsten geraden Zahl. Also 1,5 zu 2 und 2,5 auch zu 2.

    Edit: Ich vergaß zu erwähnen, das es zu Math.Round noch den Parameter MidPointRounding gibt. der Bietet 2 Methoden (ToEven und AwayFromZero), die ändern aber beide nichts an dem oben genanten Verhalten. Es wird immer zur nächsten geraden Zahl gerundet.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „gonzo16“ ()

    gonzo16 schrieb:

    gibt es in VB wirklich keine Funktion, die mathematisch richtig rundet?


    de.wikipedia.org/wiki/Rundung#Mathematische_Rundung
    Die Mathematische (auch geodätische oder unverzerrte) Rundung ist wie folgt definiert:[1]
    1. Folgt auf die letzte beizubehaltende Ziffer eine 0, 1, 2, 3 oder 4, so wird abgerundet.
    2. Folgt auf die letzte beizubehaltende Ziffer eine 5, 6, 7, 8 oder eine 9, gefolgt von weiteren Ziffern, die nicht alle null sind, so wird aufgerundet.
    3. Folgt auf die letzte beizubehaltende Ziffer lediglich eine 5 (oder eine 5, auf die nur Nullen folgen), so wird derart gerundet, dass die letzte beizubehaltende Ziffer gerade wird.

    Regel 3 beachten! Offensichtlich geht der TE von einem falschen Algorithmus aus und VB hat recht ...

    EDIT BTW: Wenn man sich den Absatz durchliest, versteht man auch, WARUM so "merkwürdig" gerundet bei bei Regel 3 ... !
    Es wurde doch schon bereichts die Lösungdas gleiche gepostet.
    Dazu sogar mehrfach Erklärungen dazu.
    Und trotzdem schreibst du fast exakt das gleiche wie x Posts zuvor.
    Ich verstehs nicht ?(

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Eistee“ ()

    @picpflop
    Danke für den Hinweis und den Link. Hab mal wieder was dazu gelernt. Da ich aber immer nur eine einzelne Zahl runden will, werden dadurch keine Statistiken verzerrt.

    Allerdings muß ich nun den Titel dieses Threads etwas ändern. Ich will also nicht mathematisch richtig Runden, sondern kaufmännisch (also so, wie ich es dereinst mal in der Schule gelernt habe). Schade nur, dass VB dafür keine Funktion anbietet. Naja, ist net weiter schlimm, das kann man ja mit etwas zusätzlichen Code fixen.

    VB.NET-Quellcode

    1. If zahl - Int(zahl) = 0.5 Then
    2. zahlGerundet = Int(zahl) + 1
    3. Else
    4. zahlGerundet = Math.Round(zahl, 0)
    5. End If


    @Eistee
    Es wurde keine einzige Lösung auf meine Frage gepostet. Alle vorgeschlagenen Funktionen hab ich in meinem Eingangspost schon als unbrauchbar (mit Begründung) beschrieben, weil die eben nicht kaufmännisch Runden.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „gonzo16“ ()

    gonzo16 schrieb:

    das kann man ja mit etwas zusätzlichen Code fixen.

    Na ja ..

    zahl ist Double? Dann gibts ne Exception, wenn zahl größer oder kleiner als integer.minvalue bzw .maxvalue ist.
    Was passiert, wenn zahl negativ ist? zb Zahl = -2.5 ... ? Dann ist die Differenz -0.5 und nicht 0.5 weil Cint(-2.5) -2 ergibt.
    Dazu kommt bei Double das unvermeidliche Problem der "Ungenauigkeiten". So kann XX.5 - XX durchaus mal 0.500000000000001 sein ...!

    Man sieht: So GANZ trivial ist es ggf nicht immer ...
    @picoflop
    Da haste natürlich recht. Für alle Situationen taucht das nix. Nur in meinem Fall ist sicher, das a) zahl nicht größer als ca. 1400 werden kann und b) zahl nicht negativ werden kann.

    Trotzdem, nur rein interessehalber. Wie kann ich den für alle Werte eine funktionierende kaufmännische Rundung hinkriegen?

    petaod schrieb:

    http://www.schmittis-page.de/index.html?/vb/t111.htm

    Hatte ich auch gefunden. Auch keine prickelnde Lösung ...

    VB.NET-Quellcode

    1. Runden = Int(Zahl * 10 ^ Dezimalanzahl + 0.5)

    Das fliegt einem ja größentechnisch schneller um die Ohren als man "Integer.MaxValue" sagen kann ...
    Mal abgesehen davon, dass durch das multiplizieren mit 10^x ein Problem mit der Unvereinbarkeit von Zahlen zur Basis 2 und Zahlen zur Basis 10 einhergeht. Dann sollte man ggf intern besser mit Decimal rechnen.
    OK, ich danke euch allen für die vielen interessanten und hilfreichen Tipps. Mein Favorit ist:

    xtts02 schrieb:

    Ich würde grundsätzlich keine Zahl mit einer der Rundungsfunktion verändern, sondern lediglich die Ausgabe formatieren.

    So werde ich es denn machen. Ist im Grunde auch einfacher als die ganze Runderei. Guter Tipp. :thumbup: