我实际上只关注 pow有意义的一小部分输入对,因为这足以证明我的观点: 如果 x 为正,| y | < = 1,那么 pow不会溢出或下溢。这包括近四分之一的所有浮点对(正好一半的非 NaN 浮点数是正的,只有不到一半的非 NaN 浮点数小于1)。显然,还有其他输入对的 很多,对它们 pow产生有用的结果,但是我们已经确定它至少占所有输入的四分之一。
在许多情况下,通过将 n专门化为一个自然数,可以使 pow(x, n)变得更快。对于几乎所有我编写的程序,我都必须使用我自己的这个函数的实现(但是我用 C 语言编写了很多数学程序)。专业的操作可以在 O(log(n))时间内完成,但当 n较小时,一个更简单的线性版本可以更快。以下是两者的实现:
// Computes x^n, where n is a natural number.
double pown(double x, unsigned n)
{
double y = 1;
// n = 2*d + r. x^n = (x^2)^d * x^r.
unsigned d = n >> 1;
unsigned r = n & 1;
double x_2_d = d == 0? 1 : pown(x*x, d);
double x_r = r == 0? 1 : x;
return x_2_d*x_r;
}
// The linear implementation.
double pown_l(double x, unsigned n)
{
double y = 1;
for (unsigned i = 0; i < n; i++)
y *= x;
return y;
}
template<typename T>
static constexpr inline T pown(T x, unsigned p) {
T result = 1;
while (p) {
if (p & 0x1) {
result *= x;
}
x *= x;
p >>= 1;
}
return result;
}