Какое наименьшее ненулевое положительное число с плавающей точкой в ​​Perl? - PullRequest
4 голосов
/ 01 августа 2009

У меня есть программа на Perl, которая работает с вероятностями, которые иногда могут быть очень маленькими. Из-за ошибки округления иногда одна из вероятностей оказывается равной нулю. Я хотел бы проверить следующее:

use constant TINY_FLOAT => 1e-200;
my $prob = calculate_prob();
if ( $prob == 0 ) {
    $prob = TINY_FLOAT;
}

Это прекрасно работает, но я на самом деле вижу, что Perl производит числа, которые меньше, чем 1e-200 (я только что видел пролет 8.14e-314). Для моего приложения я могу изменить метод convert_prob () так, чтобы он возвращал максимум TINY_FLOAT и фактическую вероятность, но мне стало интересно, как обрабатываются числа с плавающей точкой в ​​Perl.

Какое наименьшее положительное значение с плавающей точкой в ​​Perl? Это зависит от платформы? Если так, есть ли быстрая программа, которую я могу использовать, чтобы выяснить это на моей машине?

Ответы [ 4 ]

11 голосов
/ 01 августа 2009

Согласно perldoc perlnumber, Perl использует собственный формат с плавающей запятой, где native определяется как любой компилятор C, который использовался для его компиляции. Если вас больше беспокоит точность / точность, чем скорость, взгляните на bignum .

10 голосов
/ 02 августа 2009

Остальные ответы хорошие. Вот как узнать приблизительный & epsilon; если вы не знали ничего из этой информации и не смогли опубликовать свой вопрос на SO; -)

 #!/usr/bin/perl

use strict;
use warnings;

use constant MAX_COUNT => 2000;

my ($x, $c);

for (my $y = 1; $y; $y /= 2) {
    $x = $y;
    # guard against too many iterations
    last if ++$c > MAX_COUNT;
}

printf "%d : %.20g\n", $c, $x;

Выход:

C:\Temp> thj
1075 : 4.9406564584124654e-324
8 голосов
/ 02 августа 2009

Может быть важно отметить, что это наименьшее число - это то, что называется субнормальным числом, и математика, выполненная на нем, может привести к удивительным результатам:

$ perl -wle'$x = 4.94e-324; print for $x, $x*1.4, $x*.6'
4.94065645841247e-324
4.94065645841247e-324
4.94065645841247e-324

Это потому, что он использует наименьший допустимый показатель (base-2) и мантиссу вида (base-2) 0.0000000 ... 0001. Более крупные, но все же субнормальные числа также будут иметь мантиссу, начинающуюся с 0. и увеличивая диапазон точности.

4 голосов
/ 01 августа 2009

Я на самом деле не знаю, как perl представляет числа с плавающей запятой (и я думаю, что это то, что вы настраиваете при сборке perl), но если мы предположим, что IEEE 754 используется, то для 64-битного числа с плавающей запятой epsilon будет 4.94065645841247 E-324.

...