59

.NETの組み込み関数は、基数を指数にMath.Pow()上げて結果を返します。doubledoubledouble

整数で同じことを行う最良の方法は何ですか?

追加: 結果を (int) にキャストできるようですがMath.Pow()、これは常に正しい数値を生成し、丸めエラーは発生しませんか?

4

10 に答える 10

59

かなり速いものは次のようなものかもしれません:

int IntPow(int x, uint pow)
{
    int ret = 1;
    while ( pow != 0 )
    {
        if ( (pow & 1) == 1 )
            ret *= x;
        x *= x;
        pow >>= 1;
    }
    return ret;
}

これは負の累乗を許可しないことに注意してください。それは練習問題として残しておきます。:)

追加:そうそう、ほとんど忘れていました - オーバーフロー/アンダーフロー チェックも追加してください。

于 2008-12-20T18:45:15.307 に答える
53

LINQ 誰か?

public static int Pow(this int bas, int exp)
{
    return Enumerable
          .Repeat(bas, exp)
          .Aggregate(1, (a, b) => a * b);
}

拡張機能としての使用:

var threeToThePowerOfNine = 3.Pow(9);
于 2012-08-09T09:43:26.037 に答える
21

ジョン・クックのブログリンクの数学を使用すると、

    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;
    }           

電源の種類を変更するとコードが機能しなくなるという異議に対処するために...まあ、理解できないコードを変更し、テストせずにそれを使用する人がいるという点は脇に置いておきます.....
しかし、問題、このバージョンは愚か者をその間違いから保護します... (しかし、彼らが作るかもしれない無数の他の人からではありません) 注: テストされていません。

    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;
    }

また、この再帰的な同等のものを試してください(もちろん遅いです):

    public static long IntPower(long x, int power)
    {
        return (power == 0) ? x :
            ((power & 0x1) == 0 ? x : 1) *
                IntPower(x, power >> 1);
    }
于 2008-12-21T17:24:29.400 に答える
12

どうですか:

public static long IntPow(long a, long b)
{
  long result = 1;
  for (long i = 0; i < b; i++)
    result *= a;
  return result;
}
于 2012-04-11T15:28:25.470 に答える
3

double バージョンを使用し、オーバーフロー (最大 int または最大 long を超える) をチェックし、int または long にキャストしますか?

于 2008-12-20T18:52:54.777 に答える
2

この問題に対する私のお気に入りの解決策は、古典的な分割統治法による再帰的な解決策です。実際には、乗算の回数が毎回半分になるため、n 回乗算するよりも高速です。

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);
}

注: これは、オーバーフローまたは負の n をチェックしません。

于 2011-07-01T22:25:22.483 に答える