简体   繁体   English

为什么Perl的sprintf不能正确舍入浮点数?

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

I was out looking for the rounding convention used by Perl's built-in function sprintf . 我一直在寻找Perl内置函数sprintf使用的舍入约定。

I was thinking that it does a normal rounding (eg ROUND_HALF_UP as in Java's rounding mode convention ), but digging further proved this to be wrong: 我认为它进行了正常的舍入(例如在Java的舍入模式约定中的 ROUND_HALF_UP),但挖掘进一步证明这是错误的:

> /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. 由于0.335在内部表示为略大于0.335,因此其舍入为.34,而1.335略低于1.335,因此其舍入为1.33。

This is a function of IEEE floating point numbers. 这是IEEE浮点数的函数。

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. 有关更多信息,请参阅Perl上下文,请参阅Perlfaq4“Perl是否具有round()函数” ,特别是关于中间点交替的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM