0

多項式の根を見つけるための二分法アルゴリズムを書いています。FP変数がゼロまたはその絶対値に等しいかどうかを示す私のコードの2番目の部分は、私がb-a推測するifステートメントを壊すだけです。

プログラムが for ループ (反復) を完全に停止し、p を返すようにします。そして最後に、解決策を得るためにかかった反復回数を出力したいのですが、明らかに私のprintfステートメントを使用すると、ルート(ゼロ)が取得されてもプログラムが実行され続けることがわかります。

メカニズム全体を停止し、ゼロである p の値と正確な反復回数の両方を返す方法についてのアイデアはありますか? ありがとう

double computeroots(double a, double b, double epsilon, int MaxIter)
{
    double FA = pow(a,4) -4*a +  1;
    double FB = pow(b,4) - 4*b + 1;
    double FP;
    double p;
    int i;

    for(i=0;i<MaxIter;i++) {
        if(FA * FB < 0) {
            p = a + (b-a)/2;
            FP = pow(p,4) - 4*p +1;
            if(FP == 0 || abs(b-a) < epsilon) {
                return p;
                break;
            } else if (FA * FP >0) {
                a =p;
                FA = FP;
            } else {
                b = p;
                FB = FP;
            }
            i++;
        }
    }

    printf("The number of iterations is: %d\n", i);
}
4

5 に答える 5

3

ステートメントの前にあるprintfため、ステートメントはヒットしません。ステートメントはすぐに関数を終了します。return p;breakreturn

returnステートメントをの後にprintf移動するか、 :のprintf前に移動する必要があります。return

        if(FP == 0 || abs(b-a) < epsilon)
        {
            printf("the number of iterations is : %d\n", i);
            return p;
        }
        ...

    printf("failed to converge after %d iterations\n", i);
    return p;
}
于 2013-02-14T15:12:16.773 に答える
1

必要なすべての変更をマージするには:

double computeroots(
  double a, 
  double b, 
  double epsilon, 
  size_t MaxIter, 
  size_t * pNumIter
) 
{
    double FA = pow(a,4) -4*a +  1;
    double FB = pow(b,4) - 4*b + 1;
    double FP;
    double p = NaN;
    size_t i;

    for(i=0; i<MaxIter; ++i) {
        if(FA * FB < 0) {
            p = a + (b-a)/2;
            FP = pow(p,4) - 4*p +1;
            if(FP == 0 || abs(b-a) < epsilon) {
                break;
            } else if (FA * FP >0) {
                a =p;
                FA = FP;
            } else {
                b = p;
                FB = FP;
            }
        }
    }

    *pNumIter = i;

    printf("the number of iterations is : %z\n", *pNumIter);

    return p;
}

そのように呼んでください:

double a, b, epsilon;
size_t sizeMax, sizeIterations;

... /* some initialisations here */

double d = computeroots(a, b, epsilon, sizeMax, &sizeIterations);

変更に関する注意:

  • 置き忘れを削除return
  • 最後に欠落しているリターンを追加しました
  • タイプがカウンターに適しているため、intsをに変更しましたsize_tunsigned
  • size_t反復回数を返すための追加の変数への参照を追加しました
  • の2番目のインクリメントを削除しましたi
于 2013-02-14T17:32:04.127 に答える
1

複数の値を返す必要がある場合は、out-arguments を使用して行うことができます。関数を次のように変更します

double computeroots(double a, double b, double epsilon, int MaxIter, int *numIterations)

次のように呼び出します。

int numIter;
soln = computeroots(a, b, epsilon, MaxIter, &numIter);

関数で、戻る直前に次を追加します。

*numIterations = i;
于 2013-02-14T15:15:36.323 に答える
1

声明がある場合return、そのbreak声明は役に立たない。return は関数のスコープを出て呼び出し元に戻るため、その後は命令が実行されません。

したがって、この:

return p;
break;

なる必要があります:

printf("the number of iterations is : %d\n", i);
return p;

終了条件が正しく選択されていないことがわかった場合は、より有限精度の問題だと思います。チェックしてFP == 0いますがFP、正確に等しいときではなく、0に十分近いdoubleときに停止する必要があります。FP例: abs(FP) < epsilon.

于 2013-02-14T15:13:57.260 に答える
0

double の配列を返すことができます。最初の要素は結果で、2 番目の要素は反復回数です。

または、変数への参照を関数に渡し、次のように代入します。

double compute_something(int param1, int param2, int* iterations) {
    // your code ...
    // when you want to return, use this:
    *iterations = 5;
    return 1.23;
    // your code ...
}

int iter;
double result = compute_something(1,2, &iter);

この後、result には結果が含まれ、保存した反復回数を iter します。反復回数 (明らかに整数) を double として返さないため、この解決策の方が適切である可能性があります。

于 2013-02-14T15:13:12.113 に答える