From: Moritz Bunkus Date: Thu, 4 Mar 2010 14:51:57 +0000 (+0100) Subject: Beim Runden zuerst auf acht Stellen runden, danach auf die gewünschte Anzahl X-Git-Tag: release-2.6.1beta1~33^2~3 X-Git-Url: http://wagnertech.de/git?a=commitdiff_plain;h=b36ef567192b240f29d22affafcdcd985db1d392;p=kivitendo-erp.git Beim Runden zuerst auf acht Stellen runden, danach auf die gewünschte Anzahl Die interne Repräsentation von Fließkommazahlen in modernen CPUs ist immer ungenau. Um zu vermeiden, dass man mit int() zu viel abschneidet, weil der Nachkommaanteil eben nicht ganz exakt 0 sondern z.B. 999999999999594 ist, wird zuerst auf acht Stellen gerundet, um diese Ungenauigkeit zu vermeiden. Fix für Bug 1115. --- diff --git a/SL/Form.pm b/SL/Form.pm index 956120568..8d1772061 100644 --- a/SL/Form.pm +++ b/SL/Form.pm @@ -1126,13 +1126,13 @@ sub round_amount { my ($self, $amount, $places) = @_; my $round_amount; - # Rounding like "Kaufmannsrunden" - # Descr. http://de.wikipedia.org/wiki/Rundung - # Inspired by - # http://www.perl.com/doc/FAQs/FAQ/oldfaq-html/Q4.13.html - # Solves Bug: 189 - # Udo Spallek - $amount = $amount * (10**($places)); + # Rounding like "Kaufmannsrunden" (see http://de.wikipedia.org/wiki/Rundung ) + + # Round amounts to eight places before rounding to the requested + # number of places. This gets rid of errors due to internal floating + # point representation. + $amount = $self->round_amount($amount, 8) if $places < 8; + $amount = $amount * (10**($places)); $round_amount = int($amount + .5 * ($amount <=> 0)) / (10**($places)); $main::lxdebug->leave_sub(2);