-1

まず第一に、私はプログラマーではなく物理学の学生ですので、この些細な問題を許してください。ニュートン ラフソン法を使用して 3 次方程式の根を求める関数を作成しようとしています。私はほとんど問題なく動作するコードを作成しましたが、演習のポイントは、このコードを「関数」形式にすることです。つまり、戻り値の型、パラメーター、そしてコード ブロックです。このフォームに入れようとすると、コードはコンパイルされますが、入力すると、結果 (返されるルート) がぎこちなくなります。これが私のコードです。

#include<iostream>
#include<cmath>

double roots(double,double,double,double);

int main()
{
    double x3,x2,x,con;
    std::cin>>x3,x2,x,con;

    double result=roots(x3,x2,x,con);
    std::cout<<result<<std::endl;
    system("pause");
}

double roots(double xcubecoeff, double xsquarecoeff, double xcoeff, double constant)
{
    int j=0;
    int k=0;
    int l=0;
    int m=0;
    double seedvalue1=-10;
    double seedvalue2=10;
    double seedvalue3=0.3;
    double seedvalue4=-0.3;
    double xnplus1;
    double xnplus2;
    double xnplus3;

    while(j <= 100)
    {
        //func is just the structure of the cubic equation in terms of the 
        // parameters of the function
        //derfunc is just the structure of the gneral derivitive of a cuic
        // function, again in terms of the parameters
        //seedvalues are just the initial values for x in the general cubic
        // equation. 
        //Seedvalue one goes into the loop to find the negative x root, 
        // seedvalue 2 finds the positive one, seedvalue three attempts to
        // find the one in the middle of those, however if it just finds
        // either of those again then an IF statement and seedvalue 4 are
        //used to find it.

        double func = xcubecoeff * (seedvalue1 * seedvalue1 * seedvalue1) +
                      xsquarecoeff * (seedvalue1 * seedvalue1) + 
                      xcoeff * seedvalue1 + 
                      constant;

        double derfunc = 3 * xcubecoeff * (seedvalue1 * seedvalue1) +
                         2 * xsquarecoeff * seedvalue1 + 
                         xcoeff;


        double xnplus1 = seedvalue1 - (func / derfunc);

        seedvalue1=xnplus1;
        j++;
    }


    while(k <= 100)
    {
        double func = xcubecoeff * (seedvalue2 * seedvalue2 * seedvalue2) + 
                      xsquarecoeff * (seedvalue2 * seedvalue2) + 
                      xcoeff * seedvalue2 +
                      constant;

        double derfunc = 3 * xcubecoeff * (seedvalue2 * seedvalue2) + 
                         2 * xsquarecoeff * seedvalue2 +
                         xcoeff;

        double xnplus2 = seedvalue2 - (func / derfunc);

        seedvalue2 = xnplus2;
        k++;
    }

    while(l<=100)
    {
        double func = xcubecoeff * (seedvalue3 * seedvalue3 * seedvalue3) + 
                      xsquarecoeff * (seedvalue3 * seedvalue3) +
                      xcoeff * seedvalue3 +
                      constant;

        double derfunc = 3 * xcubecoeff * (seedvalue3 * seedvalue3) + 
                         2 * xsquarecoeff * seedvalue3 + 
                         xcoeff;

        double xnplus3 = seedvalue3 - (func / derfunc);

        seedvalue3=xnplus3;
        l++;
    }

    if(seedvalue3 == seedvalue1 || seedvalue3 == seedvalue2)
    {
        while(m<=100)
        {
            double func = xcubecoeff * (seedvalue4 * seedvalue4 * seedvalue4) +
                          xsquarecoeff * (seedvalue4 * seedvalue4) + 
                          xcoeff * seedvalue4 +
                          constant;

            double derfunc = 3 * xcubecoeff * (seedvalue4 * seedvalue4) +
                             2 * xsquarecoeff * seedvalue4 + xcoeff;

            double xnplus4 = seedvalue4 - (func / derfunc);

            seedvalue4=xnplus4;
            m++;
        }

        std::cout<<seedvalue1<<std::endl;
        std::cout<<seedvalue2<<std::endl;
        std::cout<<seedvalue4<<std::endl;
    }
    else
    {

        std::cout<<seedvalue1<<std::endl;
        std::cout<<seedvalue2<<std::endl;
        std::cout<<seedvalue3<<std::endl;
    }
}

これはおそらく非常に扱いにくいコードであり、ニュートン ラフソン法を実行するためのより良い方法があると確信しています。明確にするために、標準の iostream と math を含めることから始めます。次に、関数を宣言します。名前の後に、渡すことができるパラメーターの型が続きます。次に、コードを開始します。変数 x3、x2、x、および con を double として初期化し、インポート 'cin' を使用して、ユーザーがこれらの値を入力できるようにします。これが 3 次方程式の係数になります。次に、関数を呼び出し、上記で初期化された変数名を配置します。これは、ユーザーが入力した値が関数内で使用するために関数に渡されることを意味すると思います。この下に、関数の出力を出力するようにプログラムします。

私が言うように、このコードはおそらく非常に醜く非効率的ですが、ある程度は機能しますが、この形式で機能しない理由がわかりません。

お役に立てれば幸いです。

他にご不明な点がございましたら、ご説明いたします。

4

3 に答える 3

2

1つの問題はこの行にあります

std::cin>>x3,x2,x,con;

これはあなたが思っていることをしていません!ここでのコンマは、実際には両方のオペランドを評価し、一番右の値をとる「コンマ演算子」です。優先順位が低い>>ため、行は次と同じことを意味します

((((std::cin>>x3), x2), x), con);

cinこれはから読み取りx3、次に変数を評価します。変数の評価には副作用がないため、これは何もしませんx2。4 つの変数すべてを読み取るには、次を使用できます。xcon

std::cin >> x3 >> x2 >> x >> con;

多くの場合、このようなことを検出するため、できるだけ多くのコンパイラ警告を有効にすることをお勧めします。たとえば、コードのこれらの行をコンパイルするとgcc -Wall -Wextra、次の警告が表示されます。

test.cpp: In function 'int main()':
test.cpp:5:17: warning: right operand of comma operator has no effect [-Wunused-value]
test.cpp:5:19: warning: right operand of comma operator has no effect [-Wunused-value]
test.cpp:5:22: warning: right operand of comma operator has no effect [-Wunused-value]
于 2013-10-19T22:48:41.387 に答える