Список :: Util изменяет представление моего номера? - PullRequest
0 голосов
/ 28 августа 2011

Это конечная часть скрипта, которая занимает 4 дня информации, усредняет предыдущие три дня, затем вычитает текущее значение из среднего чтобы получить дисперсию.

Первый пример верный. Однако второй пример, если вы вычли 0,00299268 из 0,002997575, равен -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

Ответы [ 3 ]

4 голосов
/ 28 августа 2011

Это округление проблема числового представления.

С perldoc perlfaq4 : Почему я получаю длинные десятичные знаки (например, 19,9499999999999) вместо цифр, которые я должен получать (например, 19,95)? :


Подробное объяснение см. В книге Дэвида Голдберга "Какой каждый компьютер?" Ученый должен знать об арифметике с плавающей точкой » (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 голос
/ 29 августа 2011

Кстати,

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];

[Это действительно должен быть комментарий, но он не будет разборчивым как комментарий.Прошу прощения за размещение.]

1 голос
/ 28 августа 2011
printf "Todays Variance from the average is %.9f\n", $variance;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...