-2

の値を計算する必要がありますarctan(x)。次のシリーズを評価して、この値を計算しました。

Arctan (x) = x – x^3/3 + x^5/5 – x^7/7 + x^9/9 - …</p>

しかし、次のコードは実際の値を計算できません。たとえば、calculate_angle(1)38.34 を返します。なんで?

const double DEGREES_PER_RADIAN = 57.296;

double calculate_angle(double x)
{
    int power=5,count=3;
    double term,result,prev_res;

    prev_res = x;
    result= x-pow(x,3)/3;

    while(abs(result-prev_res)<1e-10)
    {
        term = pow(x,power)/power;
        if(count%2==0)
            term = term*(-1);
        prev_res=result;
        result=result+term;
        ++count;
        power+=2;
       // if(count=99)
         //   break;
    }

    return result*DEGREES_PER_RADIAN;
}
4

3 に答える 3

3

編集:犯人を見つけました。stdlib.h関数が存在する を含めるのを忘れましたabsabs暗黙的に宣言されているという警告を無視したに違いありません。インクルードを削除すると結果が 38.19 になり、インクルードを含めると結果が ~45 になることを確認しました。

宣言されていない関数 (この場合は abs) が使用されている場合、コンパイラはコンパイルを停止する必要はありません。代わりに、関数がどのように宣言されているかを仮定することが許可されています (この場合、間違ったものです)。

さらに、すでに述べた他のポスターと同様にabs、 double や float ではなく int を返すため、の使用は不適切です。その間の状態はあってはなり>1e-100ません<1e-1001e-100も小さすぎます。

--

増加するのを忘れ、最初の 2 つの被加数を計算した後count:power

prev_res = x;
result= x-pow(x,3)/3;

count = 4; <<<<<<
power = 5; <<<<<<

while(abs(result-prev_res)<1e-100)
{
    term = pow(x,power)/power;
    if(count%2==1)
        term = term*(-1);

また、count変数の使用は直観に反すると考えます3。最後に使用された電力を示す場合、 like で初期化されます。しかし、その後、ループ反復は1代わりにそれを増やし2、あなたは逆に符号を決定しcount%2 == 1ますpower%4 == 3

于 2013-05-03T05:42:40.117 に答える
3

級数は tan^{-1} x に収束しますが、それほど速くはありません。次の場合にシリーズを検討しx=1ます。

1 - 1/3 + 1/5 - 1/7 + 1/9 - ...

1/9用語で切り捨てるときのエラーは何ですか? あたり1/9です。精度を得るには、用語10^{-100}が必要です。10^{100}あなたがそれを手に入れる前に、宇宙は終わるでしょう。そして、壊滅的な丸め誤差と切り捨て誤差により、答えはまったく信頼できなくなります。sで遊べる数字は 14 桁しかありませんdouble

Abramowitz や Stegun [AMS 55] などの参考文献や、http://dlmf.nist.govにある新しい NIST Digital Library of Mathematical Functionsを参照して、これらが実際にどのように行われているかを確認してください。多くの場合、テイラー級数の代わりにパデ近似を使用します。テイラー級数に固執する場合でも、チェビシェフ近似を使用して合計エラーを削減することがよくあります。

Forman Acton 著の Numerical Methods that [Usually] Work もお勧めします。または...シリーズの数値レシピ。

于 2013-05-03T05:45:00.047 に答える