Runden mit printf

18/07/2010 - 12:53 von Klaus | Report spam
Hallo,

da ich gerade was zum Thema "Perl und runden" gesucht habe, bin ich im
Internet auf diese Seite aus dem "Perl Cookbook" gestoßen:
http://answers.oreilly.com/topic/41...s-in-perl/

Wenn ich das dort angegeben Beispiel

use strict;
use warnings;
use POSIX qw(floor ceil);

printf "%8s %8s %8s %8s %8s",
qw(number even zero down up);
for my $n (-6 .. +6) {
$n += 0.5;
printf "%8g %8.0f %8s %8s %8s",
$n, $n, int($n), floor($n), ceil($n);
}

bei mir (aktuelles Activestate-Perl 5.10, Windows 7) laufen lasse, erhalte ich:

number even zero down up
-5.5 -6 -5 -6 -5
-4.5 -5 -4 -5 -4
-3.5 -4 -3 -4 -3
-2.5 -3 -2 -3 -2
-1.5 -2 -1 -2 -1
-0.5 -1 0 -1 -0
0.5 1 0 0 1
1.5 2 1 1 2
2.5 3 2 2 3
3.5 4 3 3 4
4.5 5 4 4 5
5.5 6 5 5 6
6.5 7 6 6 7

Das Ergebnis unterscheidet sich in der even-Spalte, das "round to even"
scheint hier so nicht zu funktionieren!?!

Ich habe noch experimentiert und herausgefunden, das ich genau die auf der
Webseite angegeben Resultate erhalte, wenn ich im printf in der Formatangabe
für das even-Feld die Feldbreite 8 entferne, also so àndere:
printf "%8g %.0f %8s %8s %8s",

damit erhalte ich:

number even zero down up
-5.5 -6 -5 -6 -5
-4.5 -4 -4 -5 -4
-3.5 -4 -3 -4 -3
-2.5 -2 -2 -3 -2
-1.5 -2 -1 -2 -1
-0.5 -0 0 -1 -0
0.5 0 0 0 1
1.5 2 1 1 2
2.5 2 2 2 3
3.5 4 3 3 4
4.5 4 4 4 5
5.5 6 5 5 6
6.5 6 6 6 7

Natürlich stimmt jetzt die Feldbreite nicht mehr, aber ich erhalte unter
"even" die gleichen Zahlen, wie auf der Webseite.

Vielleicht hat ja jemand eine Erklàrung zum unterschiedlichen
Rundungs-Verhalten? Für mich sieht das nach einem Bug aus...

Grüße
Klaus
 

Lesen sie die antworten

#1 Peter J. Holzer
18/07/2010 - 15:38 | Warnen spam
On 2010-07-18 10:53, Klaus wrote:
da ich gerade was zum Thema "Perl und runden" gesucht habe, bin ich im
Internet auf diese Seite aus dem "Perl Cookbook" gestoßen:
http://answers.oreilly.com/topic/41...s-in-perl/

Wenn ich das dort angegeben Beispiel

use strict;
use warnings;
use POSIX qw(floor ceil);

printf "%8s %8s %8s %8s %8s",
qw(number even zero down up);
for my $n (-6 .. +6) {
$n += 0.5;
printf "%8g %8.0f %8s %8s %8s",
$n, $n, int($n), floor($n), ceil($n);
}

bei mir (aktuelles Activestate-Perl 5.10, Windows 7) laufen lasse, erhalte ich:



[inkonsistente Ergebnisse]

Vielleicht hat ja jemand eine Erklàrung zum unterschiedlichen
Rundungs-Verhalten? Für mich sieht das nach einem Bug aus...



Perl verwendet dafür einfach die entsprechenden Funktionen der
C-Library. Das Ergebnis hàngt also vom verwendeten C-Compiler und dessen
Libraries ab. Soweit ich weiß, wird ActiveState Perl mit einer ziemlich
alten Version von VisualC compiliert. Klagen über die mangelnde Qualitàt
der Microsoftschen printf-Implementation liest man öfter.

Für Windows wird in letzter Zeit hàufig Strawberry Perl empfohlen. Ich
kann dazu selbst nichts sagen, da ich kein Windows verwende.

hp

Ähnliche fragen