>有一个数字105;
>除以1000(结果0.105)
>粗略到2位小数应为:0.11
现在,几个脚本 – 基于另一个问题的答案:
这大多是推荐的,并且大多数是使用printf的upvoted解决方案.
use 5.014; use warnings; my $i = 105; printf "%.2f\n",$i/1000; #prints 0.10
但打印错误的结果.在评论中
https://stackoverflow.com/a/1838885 @Sinan Unur说(6次评论):
Use sprintf(“%.3f”,$value) for mathematical purposes too.
但是,它“有时”不起作用……就像上面一样.
另一个推荐的解决方案Math :: BigFloat:
use 5.014; use warnings; use Math::BigFloat; my $i = 105; Math::BigFloat->precision(-2); my $r = Math::BigFloat->new($i/1000); say "$r"; #0.10 ;(
错误的结果也是如此.另一个推荐了一个bignum:
use 5.014; use warnings; use bignum ( p => -2 ); my $i = 105; my $r = $i/1000; say "$r"; #0.10 ;(
又错了. (
现在工作的人:
use 5.014; use warnings; use Math::Round; my $i = 105; say nearest(0.01,$i/1000); #GREAT prints 0.11 :)
好结果0.11,但是在这里发表评论https://stackoverflow.com/a/571740
抱怨它.
最后另一个推荐“我自己的”功能:
use 5.014; use warnings; my $i = 105; my $f = $i/1000; say myround($f,2); # 0.11 sub myround { my($float,$prec) = @_; my $f = $float * (10**$prec); my $r = int($f + $f/abs($f*2)); return $r/(10**$prec); }
也打印0.11,但无法证明它的正确性.
作为参考,我读到:
> How do you round a floating point number in Perl?
> In Perl,how can I limit the number of places after the decimal point but have no trailing zeroes?
> How do I set the floating point precision in Perl?
>和许多其他人……
>最后这也是:
http://www.exploringbinary.com/inconsistent-rounding-of-printed-floating-point-numbers/
什么给这个问题提供了一个非常好的整体观点.
我明白这是所有语言的常见问题,但毕竟请
以上阅读 – 我还有这个问题:
在perl中将浮点数舍入为N的错误方法是什么?
小数位 – 用数学上正确的方式,例如会有什么结果
像105/1000正确到N个小数位没有“惊喜”……
解决方法
N = 345 DISPLAY N # Displays 345 DISPLAY (1.2) N # Displays 3.45
在尝试正确计算销售税时,我们学到了一个有价值的技巧:
my $amount = 1.344; my $amount_rounded = sprintf "%.2f",$amount + .005; my $amount2 = 1.345; my $amount_rounded2 = sprintf "%.2f",$amount2 + .005; say "$amount_rounted $amount_rounded2"; # prints 1.34 and 1.35
通过加上1/2的精度,我正确显示圆角.当数字为1.344时,添加.005使其成为1.349,并且切掉最后一位数字显示倾斜位于1.344.当我使用1.345执行相同的操作时,添加.005使其为1.350并删除最后一位数字将其显示为1.35.
您可以使用将返回舍入金额的子例程来执行此操作.
有趣…
这个主题有一个PerlFAQ.它建议只使用printf来获得正确的结果:
use strict; use warnings; use feature qw(say); my $number = .105; say "$number"; printf "%.2f\n",$number; # Prints .10 which is incorrect printf "%.2f\n",3.1459; # Prins 3.15 which is correct
对于Pi,这可行,但不适用于.105.然而:
use strict; use warnings; use feature qw(say); my $number = .1051; say "$number"; printf "%.2f\n",$number; # Prints .11 which is correct printf "%.2f\n",3.1459; # Prints 3.15 which is correct
这看起来像是Perl在内部存储.105的方式的问题.可能类似于.10499999999,它可以正确向下舍入.我还注意到Perl警告我使用舍入和舍入作为可能的未来保留字.