How do you do *integer* exponentiation in C#?

前端 未结 11 1027
迷失自我
迷失自我 2020-11-30 08:26

The built-in Math.Pow() function in .NET raises a double base to a double exponent and returns a double result.

W

相关标签:
11条回答
  • 2020-11-30 09:06

    Use double version, check for overflow (over max int or max long) and cast to int or long?

    0 讨论(0)
  • 2020-11-30 09:07

    My favorite solution to this problem is a classic divide and conquer recursive solution. It is actually faster then multiplying n times as it reduces the number of multiplies in half each time.

    public static int Power(int x, int n)
    {
      // Basis
      if (n == 0)
        return 1;
      else if (n == 1)
        return x;
    
      // Induction
      else if (n % 2 == 1)
        return x * Power(x*x, n/2);
      return Power(x*x, n/2);
    }
    

    Note: this doesn't check for overflow or negative n.

    0 讨论(0)
  • 2020-11-30 09:09

    Using the math in John Cook's blog link,

        public static long IntPower(int x, short power)
        {
            if (power == 0) return 1;
            if (power == 1) return x;
            // ----------------------
            int n = 15;
            while ((power <<= 1) >= 0) n--;
    
            long tmp = x;
            while (--n > 0)
                tmp = tmp * tmp * 
                     (((power <<= 1) < 0)? x : 1);
            return tmp;
        }           
    

    to address objection that the code will not work if you change the type of power, well... leaving aside the point that anyone who changes code they don't understand and then uses it without testing.....
    but to address the issue, this version protects the foolish from that mistake... (But not from a myriad of others they might make) NOTE: not tested.

        public static long IntPower(int x, short power)
        {
            if (power == 0) return 1;
            if (power == 1) return x;
            // ----------------------
            int n = 
                power.GetType() == typeof(short)? 15:
                power.GetType() == typeof(int)? 31:
                power.GetType() == typeof(long)? 63: 0;  
    
            long tmp = x;
            while (--n > 0)
                tmp = tmp * tmp * 
                     (((power <<= 1) < 0)? x : 1);
            return tmp;
        }
    

    Also try this recursive equivalent (slower of course):

        public static long IntPower(long x, int power)
        {
            return (power == 0) ? x :
                ((power & 0x1) == 0 ? x : 1) *
                    IntPower(x, power >> 1);
        }
    
    0 讨论(0)
  • 2020-11-30 09:11

    Another way is:

    int Pow(int value, int pow) {
        var result = value;
        while (pow-- > 1)
            result *= value;
        return pow == 0 ? result : pow == -1 ? 1 : throw new ArgumentOutOfRangeException(nameof(pow));
    }
    
    0 讨论(0)
  • 2020-11-30 09:13

    For a short quick one-liner.

    int pow(int i, int exp) => (exp == 0) ? 1 : i * pow(i, exp-1);
    

    There are no negative exponent nor overflow checks.

    0 讨论(0)
提交回复
热议问题