9

この種の式を使用して e^x を計算することになっています。

e^x = 1 + (x ^ 1/1!) + (x ^ 2/2!) ......

私はこれまでにこのコードを持っています:

while (result >= 1.0E-20 )
{
    power = power * input;
    factorial = factorial * counter;
    result = power / factorial;
    eValue += result;
    counter++;
    iterations++;
}

私の問題は、factorial が long long 型であるため、実際には 20 を超える数を格納できないことです! そのため、プログラムがそのポイントに到達すると、おかしな数字が出力されます..

正しい解は最大で 709 の X 値を持つことができるため、e^709 は次のように出力する必要があります: 8.21840746155e+307

プログラムは C++ で書かれています。

4

4 に答える 4

32

x^nもnも!n で急速に大きくなり(それぞれ指数関数的および超指数関数的に)、使用するデータ型がすぐにオーバーフローします。一方、x^n/n! (最終的に)下がり、小さいときに停止できます。つまり、x^(n+1)/(n+1)! = (x^n/n!) * (x/(n+1))。このように、次のように言います。

term = 1.0;
for(n=1; term >= 1.0E-10; n++)
{
    eValue += term;
    term = term * x / n;
}

(コードはこのボックスに直接入力されましたが、動作するはずです。)

編集: x^n/n! という用語に注意してください。は、大きな x の場合、しばらく増加してから減少します。x=709 の場合、0 に減少する前に ~1e+306 まで上昇します。これは、double処理できる範囲の限界です (doubleの範囲は ~1e308 であり、term*xそれを押し上げます) が、正常にlong double動作します。もちろん、最終結果e xはどの項よりも大きいので、結果を収容するのに十分な大きさのデータ型を使用していると仮定すれば、問題ありません。

(x=709 のdouble場合、 を使用するだけで問題なく使用できますterm = term / n * xが、710 では機能しません。)

于 2009-05-06T02:10:24.203 に答える
4

の型をfactorialからlong longに変更するとどうなりdoubleますか?

于 2009-05-06T02:04:30.817 に答える
2

私は別の解決策を考えることができます。どこpow(e,x) = pow(10, m) * bbある>=1のか< 10、そして

m = trunc( x * log10(e) )

ここで、inlog10(e)は定数係数です。

b = pow(e,x)/pow(10, m ) = pow(e,x)/pow(e,m/log10(e)) = pow (e,x-m/log10(e))

これにより、次のようになります。

z = x-m/log10(e)

これは0から3の間にあり、b = pow(e,z)SreevartsRによって与えられたように使用されます。

そして最終的な答えは

bは基数(有効数字)、mは仮数(桁違い)です。

これはSreevartsRアプローチよりも高速であり、高精度を使用する必要がない場合があります。

幸運を祈ります。

これは、xが0未満で負の値が大きい場合でも機能します。その場合、zは0から-3の間になり、他のどのアプローチよりも高速になります。

zは-3から3であり、最初の20桁の有効数字が必要な場合、pow(e、z)式は3 ^ 37/37以降、37項までしか評価できません。= 〜3.2e-26。

于 2009-05-06T10:53:43.430 に答える
1

ここで提示されたのは、多項式を計算するためのホーナースキームの適用です。

于 2009-05-06T08:51:17.063 に答える