cubic83
Goto Top

C Sharp - Runden

Guten Morgen,

ich habe ein Problem unter C# bei dem ich den Preis eines Artikels ohne Mehrwertsteuer berechnen muss. Ich habe schon gegoogelt und heraus gefunden daß es kaufmännisches Runden und Mathematisches Runden gibt. In den diversen Foren wird dies auch mit Math.Round(MidpointRounding.AwayFromZero) gelöst. In diesen Foren sind dann auch alle froh daß es klappt, nur bei mir geht es nicht ;)


Beispiel:

Preis mit Mehrwertsteuer ist 50 €. Der Mehrwertsteuersatz ist 3%.

50 / 1,03 = 48,54368932038835;
48,54 * 1,03 = 49,9962;

Aus der 48,54 müsste 48,55 werden.

Ich habe jetzt ein Testprogramm erstellt um es mal durch zu testen.

       private void button1_Click(object sender, EventArgs e)
        {
            Double TVA = 0.3;
            Double HTVA = 0;
            Double TTC = 0;

            TTC = Convert.ToDouble(ttc.Text);
            HTVA = TTC / (0.03 + 1);

            label7.Text = HTVA.ToString();

            label1.Text = "Math.Round(" + HTVA.ToString() + ", 2, MidpointRounding.AwayFromZero): " + Math.Round(HTVA, 2, MidpointRounding.AwayFromZero).ToString();  
            label2.Text = "Math.Round(" + HTVA.ToString() + ", 2, MidpointRounding.ToEven): " + Math.Round(HTVA, 2, MidpointRounding.ToEven).ToString();  
            label3.Text = "Math.Round(" + HTVA.ToString() + ", 2): " + Math.Round(HTVA, 2).ToString();  

            label4.Text = "Math.Round(" + HTVA.ToString() + ", 3, MidpointRounding.AwayFromZero): " + Math.Round(HTVA, 3, MidpointRounding.AwayFromZero).ToString();  
            label5.Text = "Math.Round(" + HTVA.ToString() + ", 3, MidpointRounding.ToEven): " + Math.Round(HTVA, 3, MidpointRounding.ToEven).ToString();  
            label6.Text = "Math.Round(" + HTVA.ToString() + ", 3): " + Math.Round(HTVA,3).ToString();  

            label8.Text = "Math.Floor(" + HTVA.ToString() + "): " + Math.Floor(HTVA).ToString();  
            label9.Text = "Math.Ceiling(" + HTVA.ToString() + "): " + Math.Ceiling(HTVA).ToString();  

            label10.Text = "Math.Ceiling(Math.Round(" + HTVA.ToString() + ", 2, MidpointRounding.AwayFromZero)): " + Math.Ceiling(Math.Round(HTVA, 2, MidpointRounding.AwayFromZero)).ToString();  
            label11.Text = "Math.Ceiling(Math.Round(" + HTVA.ToString() + ", 2, MidpointRounding.ToEven)): " + Math.Ceiling(Math.Round(HTVA, 2, MidpointRounding.ToEven)).ToString();  
            label12.Text = "Math.Ceiling(Math.Round(" + HTVA.ToString() + ", 2)): " + Math.Ceiling(Math.Round(HTVA, 2)).ToString();  

            label13.Text = "Math.Floor(Math.Round(" + HTVA.ToString() + ", 2, MidpointRounding.AwayFromZero)): " + Math.Floor(Math.Round(HTVA, 2, MidpointRounding.AwayFromZero)).ToString();  
            label14.Text = "Math.Floor(Math.Round(" + HTVA.ToString() + ", 2, MidpointRounding.ToEven)): " + Math.Floor(Math.Round(HTVA, 2, MidpointRounding.ToEven)).ToString();  
            label15.Text = "Math.Floor(Math.Round(" + HTVA.ToString() + ", 2)): " + Math.Floor(Math.Round(HTVA, 2)).ToString();  

        }

Resultat:

math

Kann mir einer weiterhelfen?

Umgebung: Visual Studio 2017 / .NET Framwork 4.7


Vielen Dank

Content-ID: 380967

Url: https://administrator.de/contentid/380967

Ausgedruckt am: 23.11.2024 um 08:11 Uhr

emeriks
Lösung emeriks 21.07.2018 um 11:47:24 Uhr
Goto Top
Hi,
habe keine Ahnung von Kaufmannsladen. Aber wenn ich einfach mal Deinen Gedanken folge, dann hätte ich hier einen pragmatischen Ansatz. Etwas bekloppt, aber es sollte funktionieren.

Ich bleibe beim Beispiel:
(Pseudo Code)
50 / 1,03 = 48,54368932038835
Gerundet = 48,54
48,54 * 1,03 = 49,9962

x = Gerundet
Solange x * 1,03 < 50
   x += 0,001
noch mal

Solange x * 1,03 > 50
   x -= 0,001
noch mal

Gerundet = x

Habe jetzt keine Lust, daraus eine Funktion zu schreiben. Auch ob das 0,001 bei allen Werten ausreichend sein wird. Keine Ahnung. Teste es, wenn Du Lust dazu hast. Viel Spaß! face-wink

E.
Kraemer
Lösung Kraemer 21.07.2018 um 12:18:28 Uhr
Goto Top
Moin,
Zitat von @Cubic83:
Beispiel:

Preis mit Mehrwertsteuer ist 50 €. Der Mehrwertsteuersatz ist 3%.

50 / 1,03 = 48,54368932038835;
48,54 * 1,03 = 49,9962;

Aus der 48,54 müsste 48,55 werden.
falsch! Bei beiden von dir genannten Rundungsverfahren ist 48,54 richtig.
Das was du brauchst ist ein Summenerhaltendes Runden - das ist nicht mal eben mit einer Formel erledigt. Siehe https://de.wikipedia.org/wiki/Rundung#Summenerhaltendes_Runden

Gruß
Cubic83
Cubic83 21.07.2018 um 14:08:11 Uhr
Goto Top
Hallo,

habe mich bis jetzt mit Emeriks Version beschäftigt. Ich habe deinen Link jetzt kurz überflogen, und auf den ersten Blick scheint sein Ansatz ja gar nicht mal so abwegig zu sein. Ich muss jetzt leider weg und les mich heute Abend mal weiter ein.

Habe den Begriff vom Summenerhaltendes Runden bislang nie gehört.


Vielen Dank euch beiden schon mal. Habe jetzt wenigstens einen Anhaltspunkt.
marinux
Lösung marinux 22.07.2018 um 08:27:12 Uhr
Goto Top
Hi,

Benutze einem mit 100 multiplizierten Input für Math.Ceiling, den du dann anschließend wieder mit 100 dividierst. Siehe z.B. https://social.msdn.microsoft.com/Forums/de-DE/585506c9-f9c8-4c0e-b16f-e ...

Gruß
Cubic83
Cubic83 22.07.2018 aktualisiert um 12:00:55 Uhr
Goto Top
Hallo,

das habe ich jetzt auch gemacht. Allerdings mit Math.Truncate(*100) / 100.

Ich habe mich bis jetzt eingelesen und dank Kraemers Hinweis heraus gefunden daß dieses Thema quasi eine Wissenschaft für sich ist. Genau genommen kann man das so nicht richtig lösen. Es gibt einige Werte für die sich kein OhneMehrwertsteuerbetrag (Nettobetrag) rechnen lässt ohne daß man am diesem Wert rum spielt.


Grundsätzlich ist die richtige Vorgehensweise daß man in einer Datenbank den Nettobetrag und den Mehrwertsteuersatz speichert, dann zusammenrechnet und zum Schluss die kaufmänische Rundung durchführt. Mach ich im Grunde auch so, aber wegen eines speziellen Formulars musste ich jetzt den umgedrehten Fall lösen.


Konkret habe ich das Problem jetzt folgendermaßen gelöst:


Um vom Brutto zum Netto zu gelangen:


        private Double GetNetto(Double Brutto, Double MwstSatz)
        {
            Double Netto = Math.Round(Brutto / (MwstSatz + 1), 2, MidpointRounding.AwayFromZero);
            while ((Netto * (MwstSatz + 1)) < Brutto)
            {
                Netto = Netto + 0.01;
            }
            return Netto;
        }


Danach zum Anzeigen:

Math.Truncate(Netto * ((Mwstsatz/100)+1)) * 100) / 100;


Vielen Dank