.NETの組み込み関数は、基数を指数にMath.Pow()
上げて結果を返します。double
double
double
整数で同じことを行う最良の方法は何ですか?
追加: 結果を (int) にキャストできるようですがMath.Pow()
、これは常に正しい数値を生成し、丸めエラーは発生しませんか?
.NETの組み込み関数は、基数を指数にMath.Pow()
上げて結果を返します。double
double
double
整数で同じことを行う最良の方法は何ですか?
追加: 結果を (int) にキャストできるようですがMath.Pow()
、これは常に正しい数値を生成し、丸めエラーは発生しませんか?
かなり速いものは次のようなものかもしれません:
int IntPow(int x, uint pow)
{
int ret = 1;
while ( pow != 0 )
{
if ( (pow & 1) == 1 )
ret *= x;
x *= x;
pow >>= 1;
}
return ret;
}
これは負の累乗を許可しないことに注意してください。それは練習問題として残しておきます。:)
追加:そうそう、ほとんど忘れていました - オーバーフロー/アンダーフロー チェックも追加してください。
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);
ジョン・クックのブログリンクの数学を使用すると、
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);
}
どうですか:
public static long IntPow(long a, long b)
{
long result = 1;
for (long i = 0; i < b; i++)
result *= a;
return result;
}
double バージョンを使用し、オーバーフロー (最大 int または最大 long を超える) をチェックし、int または long にキャストしますか?
この問題に対する私のお気に入りの解決策は、古典的な分割統治法による再帰的な解決策です。実際には、乗算の回数が毎回半分になるため、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 をチェックしません。