所以我最近一直在研究阶数统计的一些概率分布。 在该领域,经常看到许多来自实区间 [0, 1] 的高幂数公式。
考虑数字 a ~ b ~ 0,两者都是正数。我想计算类似 a^n/b^m 的东西其中 n、m 是巨大的数字。
我的问题如下:如果我使用 C 代码,例如
double f(double a, double b, long m, long n)
{
return( pow(a, n) / pow(b, m) );
}
这会稳定吗?规则应该是首先计算 a^n,然后计算 b^m 然后除法,但是如果a^n 或 b^m 足够小,它只是零或 NaN。相反,我可以做类似的事情
double g(double a, double b, long m, long n)
{
double res;
long i;
res = 1;
for (i = 0; i < min(m, n); ++i)
{
res = res * a / b;
}
if ( n > m )
{
res = res * pow(a, n - m);
} else {
res = res / pow(b, m - n);
}
return( res );
}
您知道在这种情况下 1) 是否需要优化?如果没有,如何处理这种情况以进行快速稳定的评估?
如果你问pow()
是否通过重复乘法实现幂,答案是否定的。您可以假设它已优化,因此通过检查零分子可能实现的任何节省可能都可以忽略不计。您绝对不希望使用循环访问大量浮点计算的 for()
循环来实现这一点。
另一方面,避免除以零是一种很好的做法。
我会像这样实现你的函数:
double f(double a, double b, long m, long n) {
if (b == 0) {
// return error or infinity.
}
if (m >= n)
return pow(a / b, n) * pow(a, m - n);
else
return pow(a / b, m) / pow(b, n - m);
}
}