2009-10-30 11 views
5

Ich war auf der Suche nach der Rundungskonvention von Perls eingebauter Funktion sprintf.Warum sprintet Perl nicht runde Gleitkommazahlen richtig?

Ich dachte, dass es eine normale Rundung tut (zB ROUND_HALF_UP wie in Java's rounding mode convention), aber weiter bewiesen Graben dies falsch sein:

> /usr/local/bin/perl5.10.1 -e 'print(sprintf("%.2f", shift @ARGV)."\n");' 0.335 
0.34 
> /usr/local/bin/perl5.10.1 -e 'print(sprintf("%.2f", shift @ARGV)."\n");' 1.335 
1.33 
+7

drucken (sprintf (...))? Ich frage mich, ob es einen "printf" gibt ... – jrockway

+1

Schauen Sie sich [Perl Cookbook Rezept 2.2 - Runden von Gleitkommazahlen] an (http://books.google.com/books?id=hP4IRp8xwTkC&pg=PA64&lpg=PA64&dq= + Zahlen Rundungs ​​+ perl + Kochbuch & source = bl & OTS = ti7Tyxr3s7 & sig = gyWX-iySyiVZef0vB43ZuIaxkuw & hl = en & ei = RPzrStmzO4z0MarIvKkI & sa = X & oi = book_result & ct = Ergebnis & resnum = 1 & ved = 0CAwQ6AEwAA # v = OnePage & q = & f = false) für eine vollständigere Erklärung – heferav

Antwort

16

Sie haben durch die Tatsache, gebissen worden, dass Gleitkommazahlen sind nicht exakte Darstellungen von Dezimalbrüchen. Hier ist, was ich bekommen:

DB<1> $a=0.335 

    DB<5> print sprintf("%.19f",$a) 
0.3350000000000000200 
    DB<7> $b=1.335 

    DB<8> print sprintf("%.19f",$b) 
1.3349999999999999645 
    DB<9> 

Da 0,335 dargestellt wird intern als etwas größer als 0,335 es .34 Runden, während 1.335 ist etwas weniger als 1.335, so dass es auf 1,33 aufgerundet wird.