m.fuchs hat geschrieben: Sa 11. Jan 2025, 21:02
[*]Beim Arbeiten mit Geldbeträgen gilt eine einfache Regel:
Wann runden wir? Niemals.
[/list]
Da muss ich dir widersprechen. Sobald du die Steuer ausrechnest, rundest du, da du den Steuerbetrag selten mit 2 oder 4 Nachkommastellen abbilden kannst.
Auch hat Currency 4 Nachkommastellen, wovon wir häufig aber nur 2 Nachkommastellen im Alltag verwenden. Insofern sollte ein Programm das auch entsprechend abbilden.
Beispiel:
Du rechnest für mehrere Positionen auf einem Kassenbon die Umsatz-/Mehrwertsteuer einzeln aus, da jede Position einem anderen Steuersatz unterliegen kann und deine Buchhaltung diese pro Position verbuchen muss.
Auf dem Kassenbon möchtest du auch die gesamten Steuern ausweisen. Hier muss die ausgewiesene Steuersumme der Summe der ausgedruckten Einzelsteuern entsprechen.
Da Currency immer mit 4 Nachkommastellen rechnet, kommen unterschiedliche Summen heraus, wenn du im Programm die Steuer 4 stellig ausrechnest, aber nur 2 Stelllen ausgibst oder aber vor Ausgabe die Steuer auf 2 Nachkommastellen kürzt.
Ob man dann Rundet oder die Stellen kürzt, ist eine andere Diskussion.
Beispiel:
Code: Alles auswählen
program Project1;
{$mode objfpc}{$H+}
uses
sysutils;
// Summe eines Currency Arrays bilden
function Sum(const a: array of currency): currency;
var
c: Currency;
begin
Result := 0;
for c in a do
Result := Result + c;
end;
// Currency-Wert auf 2 Nachkommastellen kürzen
function TruncToTwoDecimals(c: currency): Currency;
begin
Result := frac(c);
Result := Result * 100;
Result := Result - frac(Result);
Result := trunc(c) + Result / 100;
end;
var
NettoBetrag, BruttoBetrag, Steuer, Steuer2Dec, Brutto2Dec: array[0..10] of currency;
i: SizeInt;
begin
randomize;
// alle 4 Nachkommastellen in Format() ausgeben
DefaultFormatSettings.CurrencyDecimals:=4;
// Währungszeichen nicht ausgeben
DefaultFormatSettings.CurrencyString:='';
WriteLn(Format('%11S %11S %11S %11S %11S', ['Netto', 'Steuer', 'Brutto', 'Steuer2Dec', 'Brutto2Dec']));
for i := low(NettoBetrag) to high(NettoBetrag) do
begin
// Für 10 Positionen einen Zufallswert mit 2 Nachkommastellen erzeugen
NettoBetrag[i] := Random(1000)+Random(99)/100;
// Steuer mit 4 Nachkommastellen
Steuer[i] := NettoBetrag[i] * 0.19;
// Steuer auf 2 Nachkommastellen kürzen
Steuer2Dec[i] := TruncToTwoDecimals(Steuer[i]);
// Bruttobetrag mit 4 Nachkommastellen
BruttoBetrag[i] := NettoBetrag[i] + Steuer[i];
// Bruttobetrag mit 2 Nachkommastellen
Brutto2Dec[i] := NettoBetrag[i] + Steuer2Dec[i];
WriteLn(Format('%11M %11M %11M %11M %11M', [NettoBetrag[i], Steuer[i], BruttoBetrag[i], Steuer2Dec[i], Brutto2Dec[i]]));
end;
WriteLn('----------- ----------- -----------');
WriteLn(Format('%11M %11M %11M %11M %11M', [Sum(NettoBetrag), Sum(Steuer), sum(BruttoBetrag), sum(Steuer2Dec), sum(Brutto2Dec)]));
Readln;
end.
Beispiel-Ausgabe
Code: Alles auswählen
Netto Steuer Brutto Steuer2Dec Brutto2Dec
575,8800 109,4172 685,2972 109,4100 685,2900
125,3000 23,8070 149,1070 23,8000 149,1000
484,3900 92,0341 576,4241 92,0300 576,4200
233,6400 44,3916 278,0316 44,3900 278,0300
367,8200 69,8858 437,7058 69,8800 437,7000
381,1300 72,4147 453,5447 72,4100 453,5400
916,8000 174,1920 1.090,9920 174,1900 1.090,9900
366,4400 69,6236 436,0636 69,6200 436,0600
763,2400 145,0156 908,2556 145,0100 908,2500
147,3500 27,9965 175,3465 27,9900 175,3400
645,8500 122,7115 768,5615 122,7100 768,5600
----------- ----------- -----------
5.007,8400 951,4896 5.959,3296 951,4400 5.959,2800
Ergo: Du führst 4,96 Cent mehr an das Finanzamt ab, wenn du die Steuer nicht auf 2 Nachkommastellen kürzst.