Perl舍入错误再次出现
显示问题的示例:
>有一个数字105; 现在,几个脚本 – 基于另一个问题的答案: 这大多是推荐的,并且大多数是使用printf的upvoted解决方案. use 5.014; use warnings; my $i = 105; printf "%.2fn",$i/1000; #prints 0.10 但打印错误的结果.在评论中
但是,它“有时”不起作用……就像上面一样. 另一个推荐的解决方案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? 我明白这是所有语言的常见问题,但毕竟请 在perl中将浮点数舍入为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 "%.2fn",$number; # Prints .10 which is incorrect printf "%.2fn",3.1459; # Prins 3.15 which is correct 对于Pi,这可行,但不适用于.105.然而: use strict; use warnings; use feature qw(say); my $number = .1051; say "$number"; printf "%.2fn",$number; # Prints .11 which is correct printf "%.2fn",3.1459; # Prints 3.15 which is correct 这看起来像是Perl在内部存储.105的方式的问题.可能类似于.10499999999,它可以正确向下舍入.我还注意到Perl警告我使用舍入和舍入作为可能的未来保留字. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |