【问题标题】:How do you do exponentiation in C?你如何在C中进行幂运算?
【发布时间】:2008-10-17 17:24:23
【问题描述】:

我试过“x = y ** e”,但没用。

【问题讨论】:

  • 您的意思是e**y 而不是y**e

标签: c


【解决方案1】:

使用pow 函数(虽然它需要floats/doubles)。

man pow:

   #include <math.h>

   double pow(double x, double y);
   float powf(float x, float y);
   long double powl(long double x, long double y);

编辑:对于2 的正整数幂的特殊情况,您可以使用位移:(1 &lt;&lt; x) 将等于2 的幂x。这有一些潜在的问题,但一般来说,它是正确的。

【讨论】:

  • 我不确定编译器优化是否仍然如此,但位移是 CPU 上最快的操作之一。如果可能,我会采用这种方法。
  • 我不明白你的答案......你能提供一些插入的例子......
  • 哪部分不明白?是位移部分吗?一般来说,pow(2, x) == (1 &lt;&lt; x)所以,pow(2, 4) == 16(1 &lt;&lt; 4) == 16)
  • 如果你想要一个快速的 2 的浮点积分幂,你可以使用 ldexp -- ldexp(1.0, 100) 会给你 2**100。也适用于负能量。
【解决方案2】:

补充Evan 所说的:C 没有内置的求幂运算符,因为它不是大多数 CPU 的原始运算。因此,它被实现为一个库函数。

此外,为了计算函数 e^x,您可以使用 exp(double)expf(float)expl(long double) 函数。

请注意,您确实想使用^ 运算符,它是按位异或 运算符。

【讨论】:

  • 我只是在学习 C,而 ^ 起初让我陷入了一个主要循环。我现在开始“明白”了,但你的提醒对我和(我敢肯定)还有数百个像我一样的人非常有价值。 +1!
  • @AlexejMagura:由于 62^3 是异或运算(0x3E ^ 0x03 in hex),结果是 0x3D(61),与 62 的立方(又名 238328 或 0x03A2F8)不一样)。
  • @AlexejMagura:好的,这很好奇。我们应该清理这些 cmets 吗?
【解决方案3】:

pow 仅适用于浮点数(实际上是doubles)。如果你想取整数的幂,并且不知道底数是2 的指数,你必须自己滚动。

通常笨方法就足够了。

int power(int base, unsigned int exp) {
    int i, result = 1;
    for (i = 0; i < exp; i++)
        result *= base;
    return result;
 }

这是一个递归解决方案,它需要 O(log n) 空间和时间,而不是简单的 O(1) 空间 O(n) 时间:

int power(int base, int exp) {
    if (exp == 0)
        return 1;
    else if (exp % 2)
        return base * power(base, exp - 1);
    else {
        int temp = power(base, exp / 2);
        return temp * temp;
    }
}

【讨论】:

  • 如果您将 int 转换为 double/float 然后再转换回 int,它会正常工作。
  • 虽然效率低,但当结果接近 INT_MAX 时,舍入误差产生影响。
【解决方案4】:

与之前的答案类似,这将很好地处理 double 的正负整数幂。

double intpow(double a, int b)
{
  double r = 1.0;
  if (b < 0)
  {
    a = 1.0 / a;
    b = -b;
  }
  while (b)
  {
    if (b & 1)
      r *= a;
    a *= a;
    b >>= 1;
  }
  return r;
}

【讨论】:

    【解决方案5】:

    函数的非递归版本并不太难——这里是整数:

    long powi(long x, unsigned n)
    {
        long p = x;
        long r = 1;
    
        while (n > 0)
        {
            if (n % 2 == 1)
                r *= p;
            p *= p;
            n /= 2;
        }
    
        return(r);
    }
    

    (将双精度值提高到整数幂的代码被破解 - 例如,必须删除处理倒数的代码。)

    【讨论】:

    • 是的,O(1) 空间 O(log n) 时间使得这比递归解决方案更好,但不太明显。
    【解决方案6】:

    或者你可以只写幂函数,递归作为一个额外的好处

    int power(int x, int y){
          if(y == 0)
            return 1;
         return (x * power(x,y-1) );
        }
    

    是的,是的,我知道这会降低空间和时间复杂度,但递归更有趣!!

    【讨论】:

      【解决方案7】:
      int power(int x,int y){
       int r=1;
       do{
        r*=r;
        if(y%2)
         r*=x;
       }while(y>>=1);
       return r;
      };
      

      (迭代)

      int power(int x,int y){
       return y?(y%2?x:1)*power(x*x,y>>1):1;
      };
      

      (如果它必须是递归的)

      imo,算法肯定是O(logn)

      【讨论】:

        猜你喜欢
        • 2010-09-27
        • 2011-06-30
        • 2015-07-20
        • 2011-04-04
        • 2018-07-18
        • 1970-01-01
        • 2017-02-02
        • 1970-01-01
        • 2023-03-12
        相关资源
        最近更新 更多