微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我的公式有问题,我不知道是哪一个,在哪里

如何解决我的公式有问题,我不知道是哪一个,在哪里

#include <iostream>
#include <iomanip>
using namespace std;

//Power function
float power (float base,int exp)
{
    if (exp < 0)
        return 1 / (base * power(base,(-exp) - 1));
    
    if (exp == 0)
        return 1;

    if (exp == 1)
        return base;

    return base * power (base,exp - 1);
}

//Factorial function
int facto (int n)
{
    return n <= 0 ? 1 : n * facto (n - 1);
}

//Cos function
float cosCalc (float rad,int precision)
{
    float cos = 0;

    int x;
    for (x = 0; x < precision; x++)
        {
            cos += power (-1,x) * power (rad,x * 2) / facto (x * 2);
        }

    return cos;
}

//Sin function
float sincalc (float rad,int precision)
{
    float sin = 0;

    int x;
    for (x = 0; x < precision; x++)
        {
            sin += power (-1,1 + (x * 2)) / facto (1 + (x * 2));
        }

    return sin;
}

//Main function
int main()
{
    int precision = 10;
    int choice;

    //Title and Menu
    //Omitted this part cause it's irrelevant//

    while (true)
    {
        //User Prompt
        cout << endl << "Please enter your choice. => ";
        cin >> choice;
        
        if (choice != 1 && choice != 8 && choice !=9)
            {
                cout << endl << "Please enter a value between 1,8 and 9.";
            }

        if (choice == 1)
            {
                int angle,anglePh;
                float rad;
                float pi = 3.14159265358979323846264338327950288419716;
                char angleType;
                float cos = 0;
                float sin = 0;

                cout << endl << "Please enter an angle. => ";
                cin >> angle;
                anglePh = angle;
                //To ensure that the angle given by the user is lower than 360 degrees
                angle %= 360;
                rad = angle * pi / 180;
                cout << anglePh << " degrees = " << rad << " radian";
                cout << endl << "Calculating Cos...";
                cos = cosCalc (rad,precision);
                cout << endl << "Cos = " << fixed << setprecision(precision) << cos;
                cout << endl << "Calculating Sin...";
                sin = sincalc (rad,precision);
                cout << endl << "Sin = " << fixed << setprecision(precision) << sin;
            }
        
        if (choice == 8)
            {
                //Allows user to change the precision
            }

        if (choice == 9)
            {
                break;
            }
    }   
}

这里是代码,如果很长,请见谅。

我的公式有问题,我无法弄清楚究竟是什么,因为当角度输入很小时它输出接近正确的值,而当角度输入较大时输出错误的值。这是输出的屏幕截图。

Screenshot of one session

你可以看到,当我输入 20 和 60 时,它输出了接近完美的答案。仅以 Cos 为例,当 Google 的答案为 0.93969262078 时,它输出 20 的 Cos = 0.9396926165;当 Google 的答案是 0.5 时,它输出 60 的 Cos = 0.4999999106。但是当数字变大时,例如 300 和 340,输出值就会变得疯狂,正如您从屏幕截图中看到的那样。

由于它在较低的输入下几乎正确地输出了 Sin 和 Cos 值,我怀疑我的幂或阶乘函数有问题。

有什么想法吗?

解决方法

您的问题是浮点错误,从数学上讲,您的算法是正确的,但您的计算机无法以足够的精度容纳大数字。您正在做模 360,但这会将 rad 放在 02*pi 之间。太多了。

我建议您在 rad-pi 之间“移动”您的输入 +pi。我尝试了以下方法,效果很好:

float cosCalc(float rad,int precision)
{
    float cos = 0;
    rad -= std::floor((rad + pi) / (2 * pi)) * (2 * pi); //< HERE 
    ...
}

如果您不想使用 std::floor,您还可以使用

在 -180 到 180 度之间移动角度
angle = (angle + 180) % 360 - 180;
,

这是意料之中的,因为您知道离泰勒级数的中心越远,它的精确度就越低。由于您将其扩展为 0,因此给它更大的角度将需要多次迭代才能获得正确的结果。

Wikipedia 对此有很好的描述:

Taylor series

在您的情况下,我建议您使用关于这两个函数的已知测角规则,并将自己限制在例如[-pi/4,pi/4]。 此外,对于较高的 x 值,您的公式将快速下溢/溢出,您可以使用霍纳的方法来简化其评估。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?