4

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

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

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

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

4

4 回答 4

11

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

于 2009-08-01T19:29:53.620 回答
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;

输出:

C:\Temp> thj
1075:4.9406564584124654e-324
于 2009-08-01T21:11:34.833 回答
8

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

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

这是因为它使用最小的允许(以 2 为底)指数和形式为(以 2 为底)0.0000000...0001 的尾数。较大但仍不正常的数字也将具有从 0 开始的尾数,并且精度范围越来越大。

于 2009-08-02T09:20:08.577 回答
4

我实际上不知道 perl 如何表示浮点数(我认为这是您在构建 perl 时配置的内容),但如果我们假设使用 IEEE 754,则 64 位浮点数的 epsilon 为 4.94065645841247E-324 .

于 2009-08-01T19:29:28.723 回答