3

これはちょっとわかりにくいですが、非常に高速に計算でき、aが0から1の間で、bが非常に大きいa^bに似た関数が必要です。多くのbについて、一度に1つのaについて計算されます。理想的には、結果は0.4%以内になります。前もって感謝します。

4

3 に答える 3

2

私のコメントを答えに引き込む:

これbは整数に丸めるのに十分な大きさであるとおっしゃっているので、1つのアプローチは、 2乗による2乗べき乗アルゴリズムを使用することです。

Math.pow()非積分パワーを処理する必要があるため、低速です。したがって、整数の累乗アルゴリズムを利用できるため、あなたのケースではより良い結果が得られる可能性があります。


いつものように、実装のベンチマークを行って、実際に。よりも高速かどうかを確認しますMath.pow()


OPが検出した実装は次のとおりです。

public static double pow(double a, int b) {
    double result = 1;
    while(b > 0) {
        if (b % 2 != 0) {
            result *= a;
            b--;
        } 
        a *= a;
        b /= 2;
    }

    return result;

}

これが私の手っ取り早い(最適化されていない)実装です:

public static double intPow(double base,int pow){
    int c = Integer.numberOfLeadingZeros(pow);

    pow <<= c;

    double value = 1;
    for (; c < 32; c++){
        value *= value;
        if (pow < 0)
            value *= base;
        pow <<= 1;
    }

    return value;
}

これはすべてのポジティブで機能するはずpowです。しかし、私はそれに対してベンチマークを行っていませんMath.pow()

于 2012-09-22T06:48:00.980 に答える
2

あなたの特定のケース(「多くのbについて一度に1つのaについて計算される」)については、次のアプローチをお勧めします。

後で特定の計算で使用するテーブルデータを準備します。

  • 可能なbごとに2^Nがbより小さくなるようにNを決定します。

  • N未満の各nについてテーブルt:t [n] = a ^(2 ^ n)を計算します。これは、t [k + 1] = t [k] *t[k]として効果的に実行されます。

a ^ bを計算します:

  • bのバイナリ表現を使用して、a^bをt[i1] t [i2] ... * t [ik]として計算します。ここで、i1..ikはbのバイナリ表現における非ゼロビットの位置です。

アイデアは、異なるbに対してa ^(2 ^ n)の値を再利用することです。

于 2012-09-22T07:11:29.713 に答える
0

Apache FastMathdouble pow(double d, int e)は、指数が整数の場合の関数を提供します。

実装はVeltkampのTwoProductアルゴリズムに基づいていますMath.pow使用法は標準機能と同様です。

import org.apache.commons.math3.util.FastMath;
// ...
FastMath.pow(3.1417, 2);
于 2018-04-30T12:51:34.970 に答える