使用 sin 和 cos 函数迭代时的 Nan 结果

Posted

技术标签:

【中文标题】使用 sin 和 cos 函数迭代时的 Nan 结果【英文标题】:Nan results when iterating using sin and cos functions 【发布时间】:2012-12-22 23:39:49 【问题描述】:

我正在使用 Code::Blocks 10.05 编译这个程序,但通常我会完成大约 10 次迭代,然后它开始在每个输出中生成 Nan。我想知道这是否是使用 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;

【问题讨论】:

我把钱花在了 asin() 函数上,这就是问题所在。没有为所有输入定义 Arcsin。问题是我的意思是它的行为正确,但结果是不希望的。 【参考方案1】:

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

【讨论】:

其实零除法会产生Inf(除非被除数是NaN本身)。 @MatteoItalia 感谢您的指出;我已经发布了一个编辑。【参考方案2】:

如果值在 [-1,+1] 之外并传递给 asin(),则结果为 nan

如果您需要检查 Nan,请尝试以下操作

if( value != value )
    printf("value is nan\n");

【讨论】:

非常感谢!我设法修复它并添加一些 if 循环以在它低于 -1 或高于 1 时进行排序。

以上是关于使用 sin 和 cos 函数迭代时的 Nan 结果的主要内容,如果未能解决你的问题,请参考以下文章

怎么用iPhone计算器的sin或cos反算角度?

怎么用verilog实现cos,sin等三角函数

三角函数全公式

cos图像和性质

c语言中cos函数的用法

高中完整的三角函数值内容是啥?