abgesehen davon, das mich das Runden bei Pascal gewaltig nervt (ich sehe im Bankers Rounding als einzige Existenzgrundlage, das Bänker sich unrechtmäßig bereichern), ist mir die nächste komische Situation aufgefallen:
Beim Runden von double-Werten rundet das System mit dem Bankers-Rounding, beim Runden von Currency-Werten so, wie ich es mal gelernt habe und damit auch so, wie ich es gerne auf meinen Rechnungen hätte:
17,50€ netto gerundet als Currency ergibt 3,325€ MwSt, also 3,33€. So weit, so schön dachte ich mir...
Um die Werte zu überprüfen, habe mir ein kleines Konsolenprogrämmchen geschrieben:
(meine internen Funktionen myRound, myRoundc spielen hier keine Rolle)
Code: Alles auswählen
program project3;
function myRound(wert: double): double;
begin
  myRound := trunc(wert + 0.5);
end;
function myRoundc(wert: currency): currency;
begin
  myRoundc := trunc(wert + 0.5);
end;
var x, zins: double;
    y: currency;
begin
  zins := 0.19;
  x := 17.5;
  y := 17.5;
  writeln;
  writeln(x * zins, ' ', Round(x * zins*100)/100, ' ', myRound(x * zins*100)/100, ' ', myRoundc(x * zins*100)/100);
  writeln(y * zins, ' ', Round(y * zins*100)/100, ' ', myRound(y * zins*100)/100, ' ', myRoundc(y * zins*100)/100);
  readln;
endDoof nur, das die Werte unter Windows und Linux nicht konsistent sind:
Code: Alles auswählen
Windows, Lazarus 3.6 / fpc 3.2.2 / 64bit und
Windows, Lazarus 2.2.6 / fpc 3.2.2 / 64bit
 3.3250000000000002E+000   3.3199999999999998E+000  3.3300000000000001E+000  3.3300000000000001E+000
 3.325000000000000000E+00  3.3300000000000001E+000  3.3300000000000001E+000  3.3300000000000001E+000
Windows, fpc 3.2.2 (aus dem Lazarusverzeichnis) /64 bit & 32bit
 3.3250000000000002E+000   3.3199999999999998E+000  3.3300000000000001E+000  3.3300000000000001E+000
 3.325000000000000000E+00  3.3300000000000001E+000  3.3300000000000001E+000  3.3300000000000001E+000
		 
Linux, Lazarus 3.0 / fpc 3.2.2 / 64bit
 3.3250000000000002E+000   3.3199999999999998E+000  3.3300000000000001E+000  3.330000000000000000E+00
 3.325000000000000000E+00  3.3199999999999998E+000  3.3300000000000001E+000  3.330000000000000000E+00
	 
Linux, fpc 3.2.2 / 64 bit
 3.3250000000000002E+000   3.3199999999999998E+000  3.3300000000000001E+000  3.330000000000000000E+00
 3.325000000000000000E+00  3.3199999999999998E+000  3.3300000000000001E+000  3.330000000000000000E+00
die zweite Zeile die mit den Currency-Variablen.
Wichtig sind hier die Werte der 2. Spalte:
3.3199 (Bankers-Rounding, abgerundet; auf dies .9999999x scheiXX ich mal, wird mit double zusammenhängen)
3.3300 (Standard-Rundung; 0.5 wird aufgerundet)
Unter Linux scheint, anders als unter Windows, auch bei Currency-Werten das Bankers-Round genutzt zu werden.
Jetzt stellt sich nur noch die Frage: was ist daran gewollt?
Es hat sich mal jemand dran gemacht, diese Funktion zu definieren:
(Pfade bei mir:)
F:\lazarus\fpc\3.2.2\source\rtl\inc\currh.inc
F:\lazarus\fpc\3.2.2\source\rtl\inc\gencurr.inc
aus gencurr.inc
Code: Alles auswählen
function round(c : currency) : int64;
      var
        rem, absrem: currency;
      begin
        { (int64(tmyrec(c))(+/-)5000) div 10000 can overflow }
        result := int64(c);
        rem := c - currency(result);
        absrem := rem;
        if absrem < 0 then
          absrem := -absrem;
        if (absrem > 0.5) or
           ((absrem = 0.5) and
            (rem > 0)) then
          if (rem > 0) then
            inc(result)
          else
            dec(result);
      end; Da steckt viel Überlegung hinter, ob die ganze rumspielerei mit den beiden Variablen sinnführender ist, als die trunc-Variante, mag ich gerade nicht beurteilen.
Aber warum schafft es Code in den fpc, wenn dieser scheinbar nicht unter allen Betriebssystemen ausgeführt wird?
PS: bei der Mehrwertsteuerberechnung tritt dieser Fehler bei allen Werten auf, bei denen der Eurobetrag ungerade ist und der Centbetrag 50.
Also 1,50€, 3,50€, 5,50€, ... 151,50€, ... 7681,50€ ...
PPS: Es muß nur einer der Werte im Round ein Currency-Wert sein, dann wird das Currency-Round durchgeführt; egal an welcher Stelle der Operanden



 Verein
Verein 
 Links
Links Suche
Suche