Kaufmännisches Runden (?)

  • VB.NET
  • .NET (FX) 4.0

Es gibt 40 Antworten in diesem Thema. Der letzte Beitrag () ist von Dksksm.

    @Drahuverar
    Ich denke in der Welt der Finanzen wird bim Endverkaufspreis einfach auf die zwei nachfolgenden Kommastellen geschaut.
    Der Rest ist einfach irrelevant.

    EDIT://

    Die Frage die dir stellen musst; Wie soll der Endpreisangezeigt werden ?
    Wenn in hundertstel --> beachte die hundertstel und runde darauf (2 Stellen nach dem Komma)
    Wenn in tausendstel --> beachte die tausendstel und runde darauf (3 Stellen nach dem Komma)

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

    @Lingo
    Scheint wohl so zu sein. Auch als ich bei ein paar Leuten von der kaufmännischen Abteilung nachgefragt habe, war das für jeden normal und oder okay..
    Ich persönlich finde das nicht gut.. :D
    ...und hoffe jedenfalls dass es bei der Bank nicht so geregelt ist. :thumbsup:
    Aber daher rührt es wohl wahrscheinlich.
    Option Strict On!

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

    Drahuverar schrieb:

    Angenommen wir haben einen Wert von '36.8849999999999'
    So wäre aus kaufmännischer Sicht folgendes das Ergebnis: 36.88
    Jetzt bin ich aber der Meinung, dass es doch .885 sind, und somit wäre es Kaufmännisch 36.89!
    Nein, ​36.88 ist richtig. Es zählt nur die erste ausgelassene Stelle.
    Mit freundlichen Grüßen,
    Thunderbolt
    Also für das kaufmännische nur die 3. Dezimalstelle überprüfen und wenn 0-4 dann abrunden ..ansonsten halt 5-9 aufrunden..
    *sigh*

    Am liebsten würde ich ja mal die Truppe, welche diese Norm erstellt hat, an einen Tisch rufen und fragen wieso man sich darauf geeinigt hat. :whistling:
    Option Strict On!
    Ich kann dir sagen wie es unser ERP System handhabt:

    würde diese Zahl rauskommen beim Rechnen --> 36,88499999999 dann steht im Endeffekt 36,88 € dort
    würde diese Zahl rauskommen beim Rechnen --> 36,88599999999 dann steht 36,89 € dort.

    Bei uns wird alles nach der 3. Stelle ignoriert und auch deswegen weil allein Währungstechnisch die 3. Stelle schon garnicht existiert.
    Wer fragt, ist ein Narr für eine Minute. Wer nicht fragt, ist ein Narr sein Leben lang.

    Snaptu schrieb:

    weil allein Währungstechnisch die 3. Stelle schon garnicht existiert.
    Nö.
    Bei Zinsen und Zinseszinsen wird mit mehr Stellen geerchnet.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ein gutes Beispiel sind komplexe Excel-Kalkulationen mit mehreren Zwischenergebnissen, die dann zum Endergebnis summiert werden:
    Wenn es sich um Währungsformat mit 2 Dezimalstellen handelt, stimmt das Ergbenis der Summenfunktion (für die Zwischenergebnisse) niemals mit der händischen Addition der Zwischenergebnisse überein.
    Excel arbeitet nämlich mit 15 Nachkommastellen.
    Korrektur auf Ebene der Zwischenergebnisse mit RUNDEN(Zelle,2 führt dann zum richtigen Ergebnis.
    Das bedeutet aber auch, das man sich in jedem Einzelfall überlegen muss, ob das Zwischenergebnis gerundet werden kann.
    Ein gute Erläuterung zur richtigen Vorgehensweise findet sich unter Verwendung der Preise und Rabatte
    Wie immer: Das Gehirn darf nie ausgeschaltet werden.
    Jetzt wollte ich das so angehen, dass ich meinen Decimal in einen String umwandel um somit die 3. Dezimalstelle lesen kann (char) und anschließend mit einem Select Case überprüfe welchen "wert" die 3. Stelle hat.

    VB.NET-Quellcode

    1. Dim val as Decimal = 36.8849999999999
    2. Dim sPuffer As String = val.ToString("N3")
    3. Dim last As Char = sPuffer(sPuffer.Length - 1)
    4. Select Case last
    5. Case "0", "1", "2", "3", "4"
    6. 'Abrunden
    7. val = RoundDown(val, 2)
    8. 'Aufrunden
    9. Case "5", "6", "7", "8", "9"
    10. val = RoundUp(val, 2)
    11. End Select


    In dem Beispiel passiert folgendes --> 36.8849999999999 wird zu 36.885 beim konvertieren in einen String..
    Wie kann ich denn "genauer" konvertieren..?

    Gruß,
    Drahuverar
    Option Strict On!
    Unabhängig der ganzen runderei: Für Geldbeträge bitte Decimal benutzen. Grund ist nicht die höhere Präzision, sondern die Tatsache, dass Decimal zur Darstellung eine Skala zur Basis 10 verwendet. (Im Gegensatz zu float und double, die nach IEE754 eine binäre Skala nutzen.)

    Btw. hat die Decimal-Struktur auch eine Round-Methode mit entsprechenden Überladungen. Ist vielleicht einen Blick Wert...
    Sorry, ich weiß der Thread ist uralt. Aber es wurde hier immer noch kein korrekter (kurzer) VB.NET Code genannt, der kaufmännisch rundet. So einen Befehl muss es ja geben - sonst hätte MS geschlafen.
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    @dive26 Wahrscheinlich hat noch keiner gemerkt, dass es Überladungen der Math.Round()-Funktion gibt, die sagt, wie gerundet werden soll:

    VB.NET-Quellcode

    1. Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
    2. Label1.Text = Math.Round(NumericUpDown1.Value, 2, MidpointRounding.AwayFromZero).ToString()
    3. Label2.Text = Math.Round(NumericUpDown1.Value, 2, MidpointRounding.ToEven).ToString()
    4. End Sub

    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Vielen Dank @RodFromGermany

    Aber ist schon sonderbar. Folgender Code ergibt bei allen drei Varianten das selbe Rundungsergebnis:

    Ergebnis: 13,37

    VB.NET-Quellcode

    1. Dim Wert As Double = 13.374999
    2. Label3.Text = Math.Round(Wert, 2).ToString()
    3. Label1.Text = Math.Round(Wert, 2, MidpointRounding.AwayFromZero).ToString()
    4. Label2.Text = Math.Round(Wert, 2, MidpointRounding.ToEven).ToString()


    Ergebnis: 13,38 (sollte das mathematisch gerundet nicht 13,37 sein ????)

    VB.NET-Quellcode

    1. Dim Wert As Double = 13.37544444
    2. Label3.Text = Math.Round(Wert, 2).ToString()
    3. Label1.Text = Math.Round(Wert, 2, MidpointRounding.AwayFromZero).ToString()
    4. Label2.Text = Math.Round(Wert, 2, MidpointRounding.ToEven).ToString()


    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

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

    Also vom normalen Runden her wäre das ok. Ab 5 wird aufgerundet, da im 2ten Beispiel der dritte Wert nach dem Komma eine 5 ist wird dort aufgerundet.

    Da du auf 2 stellen rundest und dabei nicht in die Nähe der nächsten Ganzzahl kommst ( wäre meiner Meinung nach der Wert vor dem Komma), ist das Ergebnis so richtig.

    Versuch das mal mit 13.5 dann wirst du die unterschiede sehen.
    Rechtschreibfehler betonen den künstlerischen Charakter des Autors.
    @dive26 Ich habe das NUD auf 3 Nachkommastellen mit einem Increment von 0,001 eingestellt.
    Beim Runden werden ja alle vorhandenen Nachkommastellen berücksichtigt.
    Wenn Du das nicht willst, musst Du zunächst auf 3 Stellen und das Ergebnis weiter auf 2 Stellen runden.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Coole sache das MidpointRounding.AwayFromZero

    Es macht genau das was es soll.

    Freundliche Grüsse

    exc-jdbi

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Public Module CommercialRound
    4. Private Rand As New Random
    5. Public Sub Main()
    6. Dim sz = 100I
    7. Dim d = GetRngDoubles(sz)
    8. Dim _round = New List(Of Double)
    9. Dim _roundjagg = New List(Of Double())
    10. Array.ForEach(Enumerable.Range(0, sz).ToArray,
    11. Sub(x) _round.Add(RoundCommercial(d(x))))
    12. Array.ForEach(Enumerable.Range(0, sz).ToArray,
    13. Sub(x) _roundjagg.Add({d(x), RoundCommercial(d(x))}))
    14. Dim _round05 = New List(Of Double)
    15. Dim _round05jagg = New List(Of Double())
    16. Array.ForEach(Enumerable.Range(0, sz).ToArray,
    17. Sub(x) _round05.Add(Round05Commercial(d(x))))
    18. Array.ForEach(Enumerable.Range(0, sz).ToArray,
    19. Sub(x) _round05jagg.Add({d(x), Round05Commercial(d(x))}))
    20. Dim val1 = 13.374999
    21. Dim valround1 = RoundCommercial(val1)
    22. Dim val2 = 13.37544444
    23. Dim valround2 = RoundCommercial(val2)
    24. Stop
    25. End Sub
    26. Private Function RoundCommercial(value As Double) As Double
    27. Return Math.Round(Math.Round(value / 0.01, 2) * 0.01,
    28. 2, MidpointRounding.AwayFromZero)
    29. End Function
    30. Private Function Round05Commercial(value As Double) As Double
    31. Return Math.Round(Math.Round(value / 0.05, 0) * 0.05,
    32. 2, MidpointRounding.AwayFromZero)
    33. End Function
    34. Private Function GetRngDoubles(size As Int32) As Double()
    35. If size > 0 Then
    36. Dim res = New List(Of Double)(size)
    37. Array.ForEach(Enumerable.Range(0, size).ToArray,
    38. Sub(x) res.Add(Rand.NextDouble * Rand.Next(11, 21)))
    39. Return res.ToArray
    40. End If
    41. Return Nothing
    42. End Function
    43. End Module

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „exc-jdbi“ ()