7

私は次の機能を持っています:

static bool isPowerOf(int num, int power)
{
        double b = 1.0 / power;
        double a = Math.Pow(num, b);
        Console.WriteLine(a);
        return a == (int)a;
}

分析用の印刷機能を挿入しました。

関数を呼び出す場合:

isPowerOf(25, 2)

25 に等しいので、true を返します5^2。しかし、16807 を呼び出すと7^5、次のようになります。

isPowerOf(16807, 5)

この場合、'7' を出力しますが、a == (int)afalse を返します。

手伝ってくれますか?ありがとう!

4

4 に答える 4

6

丸め誤差に小さいイプシロンを使用してみてください。

return Math.Abs(a - (int)a) < 0.0001;

aharold が示唆したように、3.99999 のように、たまたま整数値よりわずかに小さい場合に備えて、丸めたほうがよいでしょう。

return Math.Abs(a - Math.Round(a)) < 0.0001;
于 2012-07-06T09:43:59.740 に答える
5

この問題を解決する比較が提案されていますが、ここで実際に問題となるのは、浮動小数点がまったく関与してはならないということです。本質的に不正確な測定値で行われた計算の近似値ではなく、整数に関する質問に対する正確な答えが必要です。

では、他にどのようにこれを行うことができますか?

最初に頭に浮かぶのはチートです。

double guess = Math.Pow(num, 1.0 / power);
return num == exponentiateBySquaring((int)guess, power) ||
       num == exponentiateBySquaring((int)Math.Ceil(guess), power);
       // do NOT replace exponentiateBySquaring with Math.Pow

guessが 1 オフ未満である限り機能します。ただし、その条件が常に満たされるとは限らないため、入力に対して常に機能することを保証することはできません。

baseそこで次に思いつくのはexponentiateBySquaring(base, power)、結果が に最も近いのバイナリ検索 (最初に上限を検索するバリアント) ですnum。最も近い答えが等しい場合にのみnum(そして両方とも整数であるため、この比較はクリーンです)、numは のpower累乗です。オーバーフローがない限り (あってはならない)、常に機能するはずです。

于 2012-07-06T10:04:47.933 に答える
2

Math.Powは s で動作するdoubleため、根を取るときに丸め誤差が発生します。正確なべき乗が見つかったことを確認したい場合:

  • Math.Powルートを抽出するために、現在のように実行します
  • 結果を最も近い整数に丸める
  • この整数を供給された累乗に上げ、供給されたターゲットを取得することを確認します。Math.Powの範囲の数値に対して正確になるのは、int整数乗に累乗するとき
于 2012-07-06T09:51:46.590 に答える
2

コードをデバッグすると、最初の比較で次のことがわかります。

isPowerOf(25, 2) 

a は、5.0 ここに 5.0 == 5 => を保持しています。これが、真になる理由です。

そして2番目にisPowerOf(16807, 5)

aが持っている7.0000000000000009

そして以来7.0000000000000009 != 7=> あなたは偽になっています。Console.WriteLine(a) は double を切り捨て/丸め、7 のみを表示します。

そのため、ダニのソリューションのように最も近い値を比較する必要があります

于 2012-07-06T09:49:37.617 に答える