Kaufmännisches Runden (?)

  • VB.NET
  • .NET (FX) 4.0

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

    Kaufmännisches Runden (?)

    Hey Leute :) ,

    ich bin mir sicher das dieses Thema oft durchgekaut worden ist, jedoch wollte ich nochmal nachfragen.

    Das Kaufmännische Runden geschieht wie folgt:

    Ist die Ziffer an der ersten wegfallenden Dezimalstelle eine 0, 1, 2, 3 oder 4, dann wird abgerundet.
    Ist die Ziffer an der ersten wegfallenden Dezimalstelle eine 5, 6, 7, 8 oder 9, dann wird aufgerundet.
    Quelle Wikipedia

    Jetzt habe ich folgenden Fall;
    Nach einer Berechnung erhalte ich folgendes Ergebnis: 36,885
    Folglich müsste ich die "erste wegfallende Dezimalstelle", in diesem Fall 5 aufrunden und hätte ja somit ein Ergebnis von '36,89' , richtig?

    Das heißt ich müsste mir eine kleine Funktion mit der Math-Klasse bauen, oder gibt es hierzu etwas das ich auf .NET Basis nutzen könnte?

    Danke,
    Drahuverar
    Option Strict On!
    es ist relativ simpel eigentlich.
    Du nimmst die Zahl a dann nimmst du math.floor(a) und speicherst diese Zahl in die Variable b jetzt machst du a-b und wenn das Ergebnis < 0,5 ist rundest du ab und wenns > als 0,5 ist rundest du auf.
    Wer fragt, ist ein Narr für eine Minute. Wer nicht fragt, ist ein Narr sein Leben lang.

    Drahuverar schrieb:

    richtig?
    Ja.
    Das ganze ist ziemlich blöd, weil nicht definiert ist, wie die nicht gerundete Zahl dargestellt wird:
    Wert gleich kaufmännisch runden:
    36,88499999999999 ==> 36,88
    => zuerst auf 3 Nachkommastellen runden, danach kaufmännisch runden:
    36,885 ==> 36,89
    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!

    RodFromGermany schrieb:

    weil nicht definiert ist

    Ja, oder? Find ich auch blöd. Hättest du dieses Beispiel nicht gebracht (36,88499999999999), hätte ich das nicht beachtet.
    Letzten Endes kann da viel ausmachen, es summiert sich ja alles. Das heißt pro errechneten Wert könnten dann doch 0.01 Cent, ich nenne es jetzt mal so, fehlen.

    @Snaptu
    Also wäre hier Math.Floor hier a(37), anschließend würde ich dann a(37) - b(36,88499999999999) nehmen
    Das wäre in diesem Fall kleiner 0.5 (0.1510...1)
    Okay, das wäre eigentlich eine gute Idee.


    Was ist denn genau der Unterschied von Floor zu Ceiling?
    Ich hab es zwar bei MSDN gelesen, wenn ich mir aber die Beispiele anschaue (Die Ergebnisse) ist kein Unterschied zu erkennen. ?(

    Wo soll ich denn nun die Grenze ziehen?
    Soll ich dann die Entscheidung treffen bei der 4. Nachkommastelle aufzuhören?

    Beispiel:
    36,8844 => 36,884 => 36,88
    36,8849 => 36,885 => 36,89
    36,8845 => 36,885 => 36,89


    Danke für eure Unterstützung
    Option Strict On!

    Drahuverar schrieb:

    36,8849 => 36,885 => 36,89
    Diese Rundung wäre in meinen Augen falsch, deswegen sollte da der Input der internationalen Kaufmännisch-Währungs-Rundungs-Gesellschaft ( :thumbsup: ) eingeholt werden.
    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!
    Das Kaufmännische Runden geschieht wie folgt:

    Ist die Ziffer an der ersten wegfallenden Dezimalstelle eine 0, 1, 2, 3 oder 4, dann wird abgerundet.
    Ist die Ziffer an der ersten wegfallenden Dezimalstelle eine 5, 6, 7, 8 oder 9, dann wird aufgerundet.

    Diese Rundungsregel wird durch die Norm DIN 1333 beschrieben. Das Runden wird so auch häufig bereits in der Grundschule gelehrt.

    Beispiele (jeweils Rundung auf zwei Nachkommastellen):

    13,3749… € ≈ 13,37 €
    13,3750… € ≈ 13,38 €

    Negative Zahlen werden nach ihrem Betrag gerundet, bei einer 5 also weg von null:

    −13,3749… € ≈ −13,37 €
    −13,3750… € ≈ −13,38 €

    Runden bereits gerundeter Zahlen
    Ist die Ausgangszahl bereits das Ergebnis einer Rundung, so muss für
    den Grenzfall, dass die neue Rundungsstelle 5 ist (und alle Stellen
    danach Nullen), wenn möglich auf die exakte Zahl zurückgegriffen werden
    (etwa bei mathematischen Konstanten):

    exakte Zahl bekannt: 13,374999747, gerundete Ausgangszahl: 13,3750

    → gerundete Zahl: 13,37
    exakte Zahl unbekannt, gerundete Ausgangszahl: 13,3750

    → gerundete Zahl: 13,38.


    So easy wie man denkt isses dann ja doch nicht aber @RodFromGermany telefoniert wahrscheinlich schon mit den Behörden und wirds dann erklären :D
    Wer fragt, ist ein Narr für eine Minute. Wer nicht fragt, ist ein Narr sein Leben lang.

    Snaptu schrieb:

    wenn möglich auf die exakte Zahl zurückgegriffen werden
    heißt dann ganz klar, dass die Zahl lediglich bei der Ausgabe gerundet wird, Floor und Ceil sind nicht vonnöten, es genügt .ToString("N2") oder ein äquivalentes Format:

    VB.NET-Quellcode

    1. MessageBox.Show(Math.PI.ToString("N2"))
    2. MessageBox.Show(Math.PI.ToString("0.00"))

    -----
    Das müsste eigentlich im Finanzministerium zu erfahren sein. 8o
    ---

    Bundesfinanzministerium, Monatsbericht_BMF_0603_gesamt und andere schrieb:

    Abweichungen in den Summen durch Runden der Zahlen.

    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!

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

    RodFromGermany schrieb:

    Diese Rundung wäre in meinen Augen falsch

    Gut das es ja durch DIN 1333 "geregelt" ist.. aber diese in, ich behaupte das jetzt mal, unseren Augen der letzte Rotz ist. Weil in meinen Augen diese Rundung auch falsch ist, aber ich nicht weiß, wie ich es anders machen sollte.

    Snaptu schrieb:

    Naja Floor = Boden das heißt abrunden, und ceiling = Decke das heißt aufrunden

    Ich hab mal beide Links in einem neuen Fenster geöffnet und mit hin und her gesprungen mit 'str+tab' ich hab so keinen Unterschied erkennen können, weswegen ich von den Werten her keinen Sinn erkennen konnte ^^ :|

    Wenn es um Geld geht werde ich dann wohl auf Decimal umsteigen.. :whistling:
    So wie ich es auch gelernt habe :whistling:

    Wenn ich mich ganz strikt daran halten würde, was vorgegeben ist, dann würden ja bei z.B. 1.000.000 Artikeln 10.000 Cent 'fehlen' und 100€ finde ich, sind 100€. :huh:

    RodFromGermany schrieb:

    Das müsste eigentlich im Finanzministerium zu erfahren sein.


    Edit:
    Wer ruft nun an und klärt das mit denen? 8o
    "Muss nicht!" :P
    Option Strict On!

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

    @Lingo
    Jup, bin gerade dran.
    Dachte schon ich bin mal superschlau und faul,nachdem ich floor und ceiling doch verstanden habe:

    VB.NET-Quellcode

    1. Private Function RoundMyVal(val As Double, dec As Integer) As Double
    2. Return Math.Ceiling(val * (10 ^ dec)) / (10 ^ dec)
    3. End Function


    Auf dem ersten Blick war ich zufrieden mit dem Ergebnis, aber dann beim 2. Testfall (testb-variablen) ... dann nich' mehr.

    VB.NET-Quellcode

    1. Dim testa1 As Double = 36.8839999999999
    2. Dim testa2 As Double = 36.8849999999999
    3. Dim testa3 As Double = 36.8859999999999
    4. Console.WriteLine(RoundMyVal(testa1, 3))
    5. Console.WriteLine(RoundMyVal(testa2, 3))
    6. Console.WriteLine(RoundMyVal(testa3, 3))
    7. Console.WriteLine(RoundMyVal(testa1, 2))
    8. Console.WriteLine(RoundMyVal(testa2, 2))
    9. Console.WriteLine(RoundMyVal(testa3, 2))
    10. Console.WriteLine()
    11. Console.WriteLine()
    12. Dim testb1 As Double = 36.8853999999999
    13. Dim testb2 As Double = 36.8854999999999
    14. Dim testb3 As Double = 36.8855999999999
    15. Console.WriteLine(RoundMyVal(testb1, 3))
    16. Console.WriteLine(RoundMyVal(testb2, 3))
    17. Console.WriteLine(RoundMyVal(testb3, 3))
    18. Console.WriteLine(RoundMyVal(testb1, 2))
    19. Console.WriteLine(RoundMyVal(testb2, 2))
    20. Console.WriteLine(RoundMyVal(testb3, 2))


    Dann mach ich das mal nun :D
    Option Strict On!

    Drahuverar schrieb:

    Return Math.Floor(val * (10 ^ dec)) / (10 ^ dec)
    Das kann auch vor die Hose gehen, da Du durch das Potenzieren numerische vom Arithmetikprozessor stammende Rundungsfehler erzeugst (in der 17. Stelle oder so).
    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!
    Disclaimer: Ich habe nicht alles gelesen bzw. überflogen.

    Mit Floor und komischen Dingen rumbasteln wenns auch einfach geht. Das Framework bietet die Math.Round-Methode an. Was spricht dagegen, diese zu verwenden? Das kann auch auf die gewünschte Anzahl an Nachkommastellen runden. Für Währungstypen würde ich als Datentyp übrigens Decimal benutzen.

    Oder sehe ich das falsch?
    Mit freundlichen Grüßen,
    Thunderbolt
    @Thunderbolt
    Gut im Grunde, aus der Mathematischen Sicht, ist das alles Richtig!
    Aber leider muss es im kaufmännischen gemacht (Geld und so) werden, im Grunde könnte man sagen:
    "Halte dich an die Regel/Norm 1333"

    Aber das finde ich persönlich falsch/nicht richtig.

    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!
    Das ist 1 Cent Unterschied...
    ..und abgesehen davon würde sich es ja summieren, somit bin ich mit dem kaufmännischen nicht einverstanden...

    Und deswegen halte ich mich da etwas dran auf ^^
    Option Strict On!

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