内容简介:翻译自:https://stackoverflow.com/questions/24493228/perl-rounding-error-again
显示问题的示例:
>有一个数字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警告我使用舍入和舍入作为可能的未来保留字.
翻译自:https://stackoverflow.com/questions/24493228/perl-rounding-error-again
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 再次认识 HTTP
- 再次了解CMS垃圾回收
- 再次认识ReentrantReadWriteLock读写锁
- Android-再次解读萤石云视频
- 【非广告】干货分享,再次关于性能优化
- 劫持“驱动人生”的挖矿蠕虫再次活跃
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Computational Advertising
by Kushal Dave、Vasudeva Varma / Now Publishers Inc / 2014
Computational Advertising (CA), popularly known as online advertising or Web advertising, refers to finding the most relevant ads matching a particular context on the Web. The context depends on the t......一起来看看 《Computational Advertising》 这本书的介绍吧!