pow()实现在cmath和有效的替换

时间:2014-11-11 08:28:34

标签: c++ c math cmath

我已经通过执行cmath来了解pow(a,b)计算exp(b*log(a))。当b是整数时,不应该使用它,因为它会大大减慢计算速度。

时有什么替代方案
  1. 使用相同的常量pow()计算很多a
  2. 事先知道b 绝对是一个整数?
  3. 我正在寻找在这些特定情况下有效的快速替代品。

3 个答案:

答案 0 :(得分:8)

我多年来收集的一些更快的替代方案通常依赖于函数的recursive实现,并且在有保证的情况下进行位移以处理乘法。以下内容提供了针对integerfloatdouble量身定制的功能。它们带有正常的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;
}