Perl 数值收敛与最小数大小

Perl 数值收敛与最小数大小,perl,floating-point,precision,Perl,Floating Point,Precision,我有一个计算概率值的程序 (), 但它正在输入一个非常大的负数 exp函数 exp(-626294.830)它的计算结果为零而不是非常小 它应该是正数 如何将其计算为一个非常小的浮点数? 我试过了 , 和 但是都失败了。说exp(-626294.830)是4.08589×10^-271997。。。零是一个非常接近的值(;-)虽然您已经编辑并删除了问题的上下文,但您是否真的需要处理如此微小的数字,或者是否有某种方法可以优化算法或缩放数字 无论如何,您是正确的,像Math::BigFloat->ne

我有一个计算概率值的程序 (), 但它正在输入一个非常大的负数
exp
函数
exp(-626294.830)
它的计算结果为零而不是非常小 它应该是正数

如何将其计算为一个非常小的浮点数? 我试过了 , 和 但是都失败了。

exp(-626294.830)
是4.08589×10^-271997。。。零是一个非常接近的值(
;-)虽然您已经编辑并删除了问题的上下文,但您是否真的需要处理如此微小的数字,或者是否有某种方法可以优化算法或缩放数字

无论如何,您是正确的,像
Math::BigFloat->new(“-626294.830”)->bexp
这样的代码似乎需要相当长的时间,即使有
use Math::BigFloat lib=>'GMP'的支持

目前我能提供的唯一选择是,尽管您需要指定精度

use Math::Prime::Util::GMP qw/expreal/;
use Math::BigFloat;
my $e = Math::BigFloat->new(expreal(-626294.830,272000));
print $e->bnstr,"\n";
__END__
4.086e-271997

但在我的机器上,即使这样也需要20秒才能运行,这让我们回到了其他地方的潜在优化问题。

浮点数并没有无限精度。假设数字表示为IEEE 754 double,则分数为52位,指数为11位,符号为1位。由于指数的编码方式,可以表示的最小正数为2^-1022

如果我们看一下你的数字e^-626294.830,我们可以改变基数,看到它等于2^(log_2e·-626294.830)=2^-903552.445,这明显小于2^-1022。因此,将数字近似为零是正确的


与使用任意精度的数值计算此值不同,您最好手动求解必要的方程,然后以不需要极端精度的方式进行编码。例如,不太可能需要e^-626294.830的精确值,但可能只需要震级。然后,您可以计算对数,而不是使用exp()。

我不知道您在问什么,可能只是因为我不知道您的pvalues是什么。你能帮我发一封邮件吗?你确定它“挂起”了吗?还是只是需要更长的时间才能运行?如果使用
获得正确的结果,请使用bignum/
使用bigrat,没有错误的结果,这将是一个重要的诊断。@Robert我在最后添加了一个mcve,基本上是如何让
exp(大负数)
作为一个非常小的正浮点数而不是
0
?@con不幸的是,这并不能回答我的问题,因为最重要的部分是程序是否真正“挂起”(永不返回),或者它是否工作,所以它在使用这些模块时运行缓慢是意料之中的。@con:您所写的内容甚至与MCVE不太接近。你需要阅读该链接。