The most efficient way to implement an integer bas

2018-12-31 03:14发布

What is the most efficient way given to raise an integer to the power of another integer in C?

// 2^3
pow(2,3) == 8

// 5^5
pow(5,5) == 3125

17条回答
倾城一夜雪
2楼-- · 2018-12-31 03:18

power() function to work for Integers Only

int power(int base, unsigned int exp){

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

}

Complexity = O(log(exp))

power() function to work for negative exp and float base.

float power(float base, int exp) {

    if( exp == 0)
       return 1;
    float temp = power(base, exp/2);       
    if (exp%2 == 0)
        return temp*temp;
    else {
        if(exp > 0)
            return base*temp*temp;
        else
            return (temp*temp)/base; //negative exponent computation 
    }

} 

Complexity = O(log(exp))

查看更多
浮光初槿花落
3楼-- · 2018-12-31 03:20

Ignoring the special case of 2 raised to a power, the most efficient way is going to be simple iteration.

int pow(int base, int pow) {
  int res = 1;
  for(int i=pow; i<pow; i++)
    res *= base;

  return res;
}

EDIT: As has been pointed out this is not the most efficient way... so long as you define efficiency as cpu cycles which I guess is fair enough.

查看更多
美炸的是我
4楼-- · 2018-12-31 03:21

more generic solution considering negative exponenet

private static int pow(int base, int exponent) {

    int result = 1;
    if (exponent == 0)
        return result; // base case;

    if (exponent < 0)
        return 1 / pow(base, -exponent);
    int temp = pow(base, exponent / 2);
    if (exponent % 2 == 0)
        return temp * temp;
    else
        return (base * temp * temp);
}
查看更多
查无此人
5楼-- · 2018-12-31 03:23

An extremely specialized case is, when you need say 2^(-x to the y), where x, is of course is negative and y is too large to do shifting on an int. You can still do 2^x in constant time by screwing with a float.

struct IeeeFloat
{

    unsigned int base : 23;
    unsigned int exponent : 8;
    unsigned int signBit : 1;
};


union IeeeFloatUnion
{
    IeeeFloat brokenOut;
    float f;
};

inline float twoToThe(char exponent)
{
    // notice how the range checking is already done on the exponent var 
    static IeeeFloatUnion u;
    u.f = 2.0;
    // Change the exponent part of the float
    u.brokenOut.exponent += (exponent - 1);
    return (u.f);
}

You can get more powers of 2 by using a double as the base type. (Thanks a lot to commenters for helping to square this post away).

There's also the possibility that learning more about IEEE floats, other special cases of exponentiation might present themselves.

查看更多
余生请多指教
6楼-- · 2018-12-31 03:25
int pow( int base, int exponent)

{   // Does not work for negative exponents. (But that would be leaving the range of int) 
    if (exponent == 0) return 1;  // base case;
    int temp = pow(base, exponent/2);
    if (exponent % 2 == 0)
        return temp * temp; 
    else
        return (base * temp * temp);
}
查看更多
荒废的爱情
7楼-- · 2018-12-31 03:25

I use recursive, if the exp is even,5^10 =25^5.

int pow(float base,float exp){
   if (exp==0)return 1;
   else if(exp>0&&exp%2==0){
      return pow(base*base,exp/2);
   }else if (exp>0&&exp%2!=0){
      return base*pow(base,exp-1);
   }
}
查看更多
登录 后发表回答