2009-10-30 9 views
5

Szukałem konwencji zaokrąglania używanej przez wbudowaną funkcję Perla sprintf.Dlaczego niepoprawne numery zmiennoprzecinkowe Perla nie są poprawne?

Myślałam, że robi normalne zaokrąglenie (np ROUND_HALF_UP jak w Java's rounding mode convention), ale kopanie dodatkowo okazało się, że jest źle:

> /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

print (sprintf (...))? Zastanawiam się, czy istnieje "printf" ... – jrockway

+1

Spójrz na [Perl Cookbook recipe 2.2 - zaokrąglanie liczb zmiennoprzecinkowych] (http://books.google.com/books?id=hP4IRp8xwTkC&pg=PA64&lpg=PA64&dq= zaokrąglenia + cyfry + Perl + cookbook i źródło = Bl OTS = ti7Tyxr3s7 i porządek = gyWX-iySyiVZef0vB43ZuIaxkuw & hl = pl & ei = RPzrStmzO4z0MarIvKkI & Sa = X oi = book_result & ct = wynik i resnum = 1 & at = 0CAwQ6AEwAA # v = onepage & Q = & f = fałsz) dla pełniejszego objaśnienia – heferav

Odpowiedz

16

zostałeś ugryziony przez fakt, że liczb zmiennoprzecinkowych nie są dokładne reprezentacje ułamków dziesiętnych. Oto co mam:

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> 

Od 0,335 reprezentowana jest wewnętrznie jako nieco większy niż 0,335 to zaokrągla do .34, a 1.335 jest nieco mniej niż 1,335, a więc zaokrągla się do 1,33.

Powiązane problemy