开发者

Why does Perl's sprintf not round floating point numbers correctly?

开发者 https://www.devze.com 2022-12-09 17:57 出处:网络
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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消