2009-10-30 71 views
5

我一直在寻找Perl内置函数sprintf使用的舍入约定。为什么Perl的sprintf不能正确地舍入浮点数?

我想,它正常的四舍五入(如ROUND_HALF_UP在Java's rounding mode convention),但挖进一步证明这是错误的:

> /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(...))?我不知道是否有一个“printf”... – jrockway 2009-10-31 05:31:37

+1

看看[Perl Cookbook recipe 2.2 - 舍入浮点数](http://books.google.com/books?id=hP4IRp8xwTkC&pg=PA64&lpg=PA64&dq=圆整+数字+ perl + cookbook&source = bl&ots = ti7Tyxr3s7&sig = gyWX-iySyiVZef0vB43ZuIakkuw&hl = en&ei = RPzrStmzO4z0MarIvKkI&sa = X&oi = book_result&ct = result&resnum = 1&ved = 0CAwQ6AEwAA#v = onepage&q =&f = false) – heferav 2009-10-31 09:12:55

回答

16

您已被事实浮点数不是被咬小数部分的精确表示。下面是我得到:

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> 

由于在0.335内部表示为略大于0.335它四舍五入到0.34,而1.335略小于1.335,所以舍入到1.33。