这是一个需要4天信息的脚本的结尾部分, 平均前三天,然后从平均值中减去今天的价值 得到方差。
第一个例子是正确的。
但是,如果从0.002997575减去0.00299268等于-0.000004895,则第二个示例。但是List::Util
将其列为-4.89499999999955e-06。
我需要定期记录。
use List::Util qw/sum/;
$todays_latency = $ecp_average[0];
$sum = sum $ecp_average[1] + $ecp_average[2] + $ecp_average[3] + $ecp_average[4];
$average = $sum/$#ecp_average;
$variance = $todays_latency - $average ;
print "Todays listing is $todays_latency\n";
print "The Average is $average\n";
print "Todays Variance from the average is $variance\n";
print "\n";
foreach(@ecp_average){
print "$_\n";
}
print "\n";
@ecp_average = ();
}
Eislnd1
Todays listing is 0.00376258
The Average is 0.004412365
Todays Variance from the average is -0.000649785
0.00376258
0.00371207
0.00511266
Eislnd2
Todays listing is 0.00299268
The Average is 0.002997575
Todays Variance from the average is -4.89499999999955e-06
0.00299268
0.00301986
0.00297529
答案 0 :(得分:4)
这是舍入数字表示问题。
对于长篇解释,请参阅David Goldberg的“每台计算机都是什么 科学家应该知道浮点运算“ (http://web.cse.msu.edu/~cse320/Documents/FloatingPoint.pdf)。
在内部,您的计算机代表二进制的浮点数。 数字(如两个权力)计算机无法存储所有数字 究竟。一些实数在此过程中会失去精确度。这是一个 计算机如何存储数字并影响所有计算机的问题 语言,而不仅仅是Perl。
perlnumber
显示数字的血腥细节 陈述和转换。限制小数位数 在您的号码中,您可以使用printf
或sprintf
功能。有关详细信息,请参阅
perlop
中的浮点算术。printf "%.2f", 10/3; my $number = sprintf "%.2f", 10/3;
换句话说,如果这是一个问题,请使用sprintf
围绕它:
$variance = sprintf '%.9f', $todays_latency - $average ; # Rounded to 9 d.p.
答案 1 :(得分:1)
printf "Todays Variance from the average is %.9f\n", $variance;
答案 2 :(得分:1)
顺便说一下,
my $sum = sum $ecp_average[1] + $ecp_average[2] +
$ecp_average[3] + $ecp_average[4];
毫无意义。您只传递一个号码到sum
,所以它实际上是一个无操作号码。你想要
my $sum = $ecp_average[1] + $ecp_average[2] +
$ecp_average[3] + $ecp_average[4];
或
my $sum = sum @ecp_average[1..4];
[这应该是一个评论,但作为评论它不会清晰。请原谅安置。]