I was out looking for the rounding convention used by Perl's built-in function sprintf.
I was thinking that it does a normal rounding (e.g. ROUND_HALF_UP as in Java's rounding mode convention), but digging further proved this to be wrong:
> /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
You have been bitten by the fact that floating point numbers are not exact representations of decimal fractions. Here's what I get:
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>
Since 0.335 is represented internally as slightly larger than 0.335 it rounds to .34, while 1.335 is slightly LESS than 1.335, so it rounds to 1.33.
This is a function of IEEE floating point numbers.
For more information, in a Perl context, see Perlfaq4 "Does Perl have a round() function" and in particular what it says about half-way-point alternation.
精彩评论