Why does Perl sprintf incorrectly round floating point numbers?

I was looking for a rounding convention used by the Perl sprintf built-in function.

I thought that it does normal rounding (e.g. ROUND_HALF_UP, as in the Java rounding convention ), but digging further proved that it is not:

> /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 
+5
source share
2 answers

You were bitten by the fact that floating point numbers are not exact representations of decimals. Here is 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 is rounded to 0.34, and 1.355 is slightly Less than 1.335, so it is rounded to 1.33.

+16
source

This is a function of IEEE floating point numbers.

For more information in the Perl context, see Perlfaq4 "Perl has a round () function" and, in particular, what it says about alternating with a half-point.

+6
source

All Articles