Perl中最小的非零,正浮点数是多少?

Jam*_*son 4 floating-point perl numerical

我在Perl中有一个程序可以处理偶尔会非常小的概率.由于舍入误差,有时其中一个概率为零.我想检查以下内容:

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

这工作正常,但我实际上看到Perl生成的数字小于1e-200(我刚看到8.14e-314飞过).对于我的应用程序,我可以更改calculate_prob(),以便它返回TINY_FLOAT的最大值和实际概率,但这让我对如何在Perl中处理浮点数感到好奇.

Perl中最小的正浮点值是多少?它是平台依赖的吗?如果有,是否有一个快速程序,我可以用来在我的机器上找出它?

Cha*_*ens 11

根据perldoc perlnumber,Perl使用本机浮点格式,其中native被定义为用于编译它的C编译器.如果您更担心精度/准确度而不是速度,请查看bignum.


Sin*_*nür 10

其他答案都很好.如果您不知道任何该信息并且无法在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;
Run Code Online (Sandbox Code Playgroud)

输出:

C:\Temp> thj
1075 : 4.9406564584124654e-324


yst*_*sth 8

值得注意的是,最小的数字是所谓的次正规数,并且对其进行的数学运算可能会产生令人惊讶的结果:

$ perl -wle'$x = 4.94e-324; print for $x, $x*1.4, $x*.6'
4.94065645841247e-324
4.94065645841247e-324
4.94065645841247e-324
Run Code Online (Sandbox Code Playgroud)

那是因为它使用了最小的允许(base-2)指数和形式的尾数(base-2)0.0000000 ... 0001.较大但仍然是次正规的数字也将具有从0开始的尾数和不断增加的精度范围.