¿List :: Util está cambiando la representación de mi número?

This is the end part of a script that takes 4 days information, averages the previous three days, then subtracts todays value from the average to get the variance.

The first example is correct. However the second example if you subtract 0.00299268 from 0.002997575 equals -0.000004895. However List::Util is listing it as -4.89499999999955e-06.

I need to get it in regular notation.

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 = ();
}

Salida

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

preguntado el 27 de agosto de 11 a las 23:08

Your text says average 3 days, but your code averages 4 days! You seem to expect that @ecp_average contains 5 values, but your output shows only 3 values! Your problem does not have anything to do with List::Util. -

Also, your code has unbalanced parentheses, and variables that aren't initialized before they're used. Post an entire (runnable) code sample or else we can't really identify where the problem may be. -

Yeah, it is desigend to run just on friday for now, and i worked on this a few days before i posted it. -

3 Respuestas

Esto es una redondeo numerical representation issue.

Desde perldoc perlfaq4 : Why am I getting long decimals (eg, 19.9499999999999) instead of the numbers I should be getting (eg, 19.95)? :


For the long explanation, see David Goldberg's "What Every Computer Scientist Should Know About Floating-Point Arithmetic" (http://web.cse.msu.edu/~cse320/Documents/FloatingPoint.pdf).

Internally, your computer represents floating-point numbers in binary. Digital (as in powers of two) computers cannot store all numbers exactly. Some real numbers lose precision in the process. This is a problem with how computers store numbers and affects all computer languages, not just Perl.

perlnumber shows the gory details of number representations and conversions. To limit the number of decimal places in your numbers, you can use the printf or sprintf función.

See Floating Point Arithmetic in perlop para más información.

printf "%.2f", 10/3;
my $number = sprintf "%.2f", 10/3;

In other words, if this is an issue, round it using sprintf:

$variance = sprintf '%.9f', $todays_latency - $average ;  # Rounded to 9 d.p.

Respondido 28 ago 11, 04:08

printf "Todays Variance from the average is %.9f\n", $variance;

Respondido 28 ago 11, 04:08

Por cierto,

my $sum = sum $ecp_average[1] + $ecp_average[2] +
              $ecp_average[3] + $ecp_average[4];

makes no sense. You are only passing one number to sum, so it's effectively a no-op. You want

my $sum = $ecp_average[1] + $ecp_average[2] +
          $ecp_average[3] + $ecp_average[4];

or

my $sum = sum @ecp_average[1..4];

[This should really be a comment, but it wouldn't be legible as a comment. Please pardon the placement.]

Respondido 29 ago 11, 23:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.