我已经通过执行cmath
来了解pow(a,b)
计算exp(b*log(a))
。当b
是整数时,不应该使用它,因为它会大大减慢计算速度。
pow()
计算很多的a
b
绝对是一个整数?我正在寻找在这些特定情况下有效的快速替代品。
答案 0 :(得分:8)
我多年来收集的一些更快的替代方案通常依赖于函数的recursive
实现,并且在有保证的情况下进行位移以处理乘法。以下内容提供了针对integer
,float
和double
量身定制的功能。它们带有正常的disclaimer:
,但速度并不快,并非所有可能的测试都已运行,并且用户应该在调用之前验证输入是否正确并且返回... blah,blah,blah ..但是,它们非常有用:
我相信正确的归属归于Geeks for Geeks Pow(x,n),正如蓝月所指出的那样。我早就失去了链接..看起来像他们。 (减去一两个调整)。
/* Function to calculate x raised to the power y
Time Complexity: O(n)
Space Complexity: O(1)
Algorithmic Paradigm: Divide and conquer.
*/
int power1 (int x, unsigned int y)
{
if (y == 0)
return 1;
else if ((y % 2) == 0)
return power1 (x, y / 2) * power1 (x, y / 2);
else
return x * power1 (x, y / 2) * power1 (x, y / 2);
}
/* Function to calculate x raised to the power y in O(logn)
Time Complexity of optimized solution: O(logn)
*/
int power2 (int x, unsigned int y)
{
int temp;
if (y == 0)
return 1;
temp = power2 (x, y / 2);
if ((y % 2) == 0)
return temp * temp;
else
return x * temp * temp;
}
/* Extended version of power function that can work
for float x and negative y
*/
float powerf (float x, int y)
{
float temp;
if (y == 0)
return 1;
temp = powerf (x, y / 2);
if ((y % 2) == 0) {
return temp * temp;
} else {
if (y > 0)
return x * temp * temp;
else
return (temp * temp) / x;
}
}
/* Extended version of power function that can work
for double x and negative y
*/
double powerd (double x, int y)
{
double temp;
if (y == 0)
return 1;
temp = powerd (x, y / 2);
if ((y % 2) == 0) {
return temp * temp;
} else {
if (y > 0)
return x * temp * temp;
else
return (temp * temp) / x;
}
}
答案 1 :(得分:2)
您可能需要查看this。这是替代pow功能的快速算法。
答案 2 :(得分:2)
非递归非浮点答案
将uintmax_t/intmax_t
替换为您所需的类型。未检测到溢出。
uintmax_t powjuu(unsigned x, unsigned y) {
uintmax_t z = 1;
uintmax_t base = x;
while (y) {
if (y & 1) { // or y%2
z *= base;
}
y >>= 1; // or y /= 2
base *= base;
}
return z;
}
intmax_t powjii(int x, int y) {
if (y < 0) {
switch (x) {
case 0:
return INTMAX_MAX;
case 1:
return 1;
case -1:
return y % 2 ? -1 : 1;
}
return 0;
}
intmax_t z = 1;
intmax_t base = x;
while (y) {
if (y & 1) {
z *= base;
}
y >>= 1;
base *= base;
}
return z;
}