-1

所以我最近一直在研究订单统计的一些概率分布。在那个领域,很常见的是从实数区间 [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) 在这种情况下是否需要优化?如果不是,如何处理此类情况以进行快速稳定的评估?

4

1 回答 1

3

如果你问是否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);
  }
}
于 2013-10-20T13:38:08.660 回答