3

私はCode::Blocks 10.05を使用してこのプログラムをコンパイルしていますが、通常、すべての出力でNanの生成を開始する前に、約10回の反復が行われます。これがcos関数とsin関数を使用することによって引き起こされる問題であるかどうか、およびこれを回避するための適切な回避策があったかどうか疑問に思いました。

私は大学のプロジェクトに取り組んでいるので、多くの反復を作成する必要があります。そのため、それも正確である必要があります。sinとcosの使用を回避する方法についていくつかの記事を調べましたが、いくつかの式に厳密に従う必要があります。そうしないと、生成される結果が不正確になる可能性があるため、妥協するかどうかはわかりません。

    struct Particle // Need to define what qualities our particle has
{
   double dPosition;
   double dAngle;

};

Particle Subject;

void M1(double &x, double &y) //Defines movement if particle doesn't touch inner   boundary
{
    x = x + 2*y;
}

double d = 0.25; //This can and will be changed when I need to find a distance between
                // the two cricles at a later stage


void M2(double &x,double &y, double d) //Defines movement of a particle if it impacts the inner boundary
{
    double z = asin(-(sin(y)+d*cos(x + y))/0.35);
    double y1 = y;
    y = asin(-0.35*sin(z) + d*cos(x + y + 2*z));
    x = y + y1 + x + 2*z;
}

int main()
{
    cout << "Please tell me where you want this particle to start positions-wise? (Between 0 and 2PI" << endl;
    cin >> Subject.dPosition;
    cout << "Please tell me the angle that you would like it to make with the normal? (Between 0 and PI/2)" << endl;
    cin >> Subject.dAngle;
    cout << "How far would you like the distances of the two middle circles to be?" << endl;
    double d;
    cin >> d;

    // These two functions are to understand where the experiment begins from.
    // I may add a function to change where the circle starts however I will use radius = 0.35 throughout

    cout << "So position is: " << Subject.dPosition << endl;
    cout << "And angle with the normal is: " << Subject.dAngle <<endl;

    int n=0;
    while (n <= 100) //This is used to iterate the process and create an array of Particle data points
    {               // in order to use this data to build up Poincare diagrams.

    {
        while (Subject.dPosition > 2*M_PI)
            Subject.dPosition = Subject.dPosition - 2*M_PI;
    }
    {
        if (0.35 >= abs(0.35*cos(Subject.dPosition + Subject.dAngle)+sin(Subject.dAngle))) //This is the condition of hitting the inner boundary
            M2(Subject.dPosition, Subject.dAngle, d); //Inner boundary collision
        else
            M1(Subject.dPosition, Subject.dAngle); // Outer boundary collision
    };
    cout << "So position is: " << Subject.dPosition << endl;
    cout << "And angle with the normal is: " << Subject.dAngle <<endl;
    n++;
}
    return 0;
}
4

2 に答える 2

3

Nanは、無限、ゼロ除算、および表現できない数のその他のバリエーションを示すものとして c++ に示されています。

編集

Matteo Itallia が指摘したようにinf、無限/ゼロ除算に使用されます。私はこれらのアプローチを見つけました:

template<typename T>
inline bool isnan(T value) {
    return value != value;
}

// requires #include <limits>
template<typename T>
inline bool isinf(T value) {
    return std::numeric_limits<T>::has_infinity &&
        value == std::numeric_limits<T>::infinity();
}

参照: http://bytes.com/topic/c/answers/588254-how-check-double-inf-nan

于 2012-12-22T23:43:01.673 に答える
0

値が [-1,+1] の範囲外で asin() に渡された場合、結果は nan になります

Nan を確認する必要がある場合は、次の手順を試してください。

if( value != value ){
    printf("value is nan\n");
}
于 2012-12-22T23:55:29.437 に答える