1

我正在为我们学校做一个项目,我们需要创建一个程序来计算 和 的泰勒展开级数的近似值sin xcos x仅使用<stdio.h>使用除 之外的用户定义函数int main(),所有角度从-180180增量为+5。以下是我的代码:

#include <stdio.h>
#define PI   3.141592653589
#define NUMBER_OF_TERMS    10

int
main()
{
    int cosctr, sinctr;
    double ctr, radi;
    double cosaccu, costerm, sinaccu, sinterm;

    for (ctr = -180; ctr < 185; ctr = ctr + 5) {
        radi = ctr * PI/180.0;
        cosctr = 1;
        cosaccu = 1;
        costerm = 1;
        sinctr = 2;
        sinaccu = radi;
        sinterm = radi;
        while (cosctr <= 2*NUMBER_OF_TERMS) {
            costerm = costerm*(-1)*(radi*radi)/(cosctr*(cosctr + 1));
            cosaccu = cosaccu + costerm;
            cosctr+=2;
        } do {
            sinterm = sinterm*(-1)*(radi*radi)/(sinctr*(sinctr + 1));
            sinaccu = sinaccu + sinterm;
            sinctr+=2;
        } while (sinctr <= 2*NUMBER_OF_TERMS);
        printf("%.2lf      %.12lf      %.12lf      %.12lf\n", ctr, radi, cosaccu, sinaccu);
    } return 0;
}

上面的代码对于 15 项扩展近似是准确的。但是,如果我更改NUMBER_OF_TERMS为例如 5 或 10,则近似值有缺陷。
有什么建议么?

让我澄清一下:我需要获得 5 个术语、10 个术语和 15 个术语的近似值。我不能使用除<stdio.h>. 我不能使用除此之外的任何其他功能int main()(对于我之前的解释含糊不清,我深表歉意)。
请使用随附的更正代码进行回答。

4

5 回答 5

1

高进动的关键,但简单的计算sind(degrees)和是首先使用通常的三角调整和度数排列cosd(degrees),首先将度数的范围减少到 0 到 90(甚至 0 到 45) 。

减少:
angle = fmod(angle, 360)// 减少 (-360..360) 或使用 a = a - (int)(a/360)
sin(x) = -sin(-x) // 减少到 [0..360)
cos(x) = cos(-x) // 减少到 [0..360)
sin(x) = -sin(x-180) // 减少到[0..180)
cos(x) = -cos(x-180) // 减少到 [0..180)
sin(x) = cos(90-x) // 减少到 [0..90)
进一步减少:
对于 [45-90) 使用 sin(x) = cos(90-x)// 减少到 [0..45)

然后转换为弧度并使用泰勒级数展开。

例子

注意:由于代码处理的是double,通常为 17 位精度,因此无需使用课程 PI 近似值。

// #define PI   3.141592653589
#define PI   3.1415926535897932384626433832795
于 2015-11-02T02:07:55.037 回答
1

我试过你的代码;它对我来说很好,因为它看起来像它设计的那样。这是您的代码在 5 项和 10 项处的余弦输出与 Mathematica 计算的相同近似值之间的比较。他们同意<10^-12,即您输出的精度。:

在此处输入图像描述

我在您的代码中看到的唯一问题是,按照您设计循环的方式,如果您计算展开中的第一项,您实际上是在考虑NUMBER_OF_TERMS + 1项(即余弦的常数项,线性项正弦。)您从第一个术语开始,然后您的循环添加另一个NUMMBER_OF_TERMS术语。如果这不是设计使然,那么您实际上是在以您期望的更高精度逼近函数。

于 2015-11-01T10:34:59.203 回答
0

我在另一个用户的帮助下弄清楚了。原来我正在计算术语 + 1,使答案比预期的更准确。15 项后的变化超过了小数点后第 12 位,因此没有显示在结果中。

#include <stdio.h>
#define PI   3.141592653589
#define NUMBER_OF_TERMS 10 // 5 and 15 work as well

int
main()
{
    int cosctr, sinctr;
    double ctr, radi;
    double cosaccu, costerm, sinaccu, sinterm; // accu will be final answer, term will be added to accu

    for (ctr = -180; ctr < 185; ctr+=5) { // for loop; ctr initialized at -185 and added to in increments of 5 to produce degrees
        radi = ctr * PI/180.0; // calculation for radians (assigned to radi)
        cosctr = 1; // initialization for cos counter; must be included in loop to allow correct calculations of cos
        cosaccu = 1; // first term is 1
        costerm = 1; // base term, to be multiplied with termcalc formula
        sinctr = 2; // initialization for sin counter; must be included in loop to allow correct calculations of sin
        sinaccu = radi; // first term is x, or degrees in radians (radi)
        sinterm = radi; // base term for sin
     // cos calculation
     while (cosctr < 2*NUMBER_OF_TERMS-1) { // accuracy check, 2* since increments of 2; NOTE: actual values are (1, 3, 5,...)
        costerm = costerm*(-1)*(radi*radi)/(cosctr*(cosctr + 1)); // TERMCALC FORMULA; multiplying previous term with formula creates next term
        cosaccu = cosaccu + costerm; // addition of new term to previous sum; dependent on accuracy (NUMBER_OF_TERMS)
        cosctr+=2;
     } do { // sin calculation; identical to cos, albeit with substituted vars
        sinterm = sinterm*(-1)*(radi*radi)/(sinctr*(sinctr + 1));
        sinaccu = sinaccu + sinterm;
        sinctr+=2;
     } while (sinctr < 2*NUMBER_OF_TERMS-1); // accuracy check, 2* since increments of 2; NOTE: actual values are (2, 4, 6,...)
     printf("%.2lf\t%.12lf\t%.12lf\t%.12lf\n", ctr, radi, cosaccu, sinaccu); // final display; /t used for convenience
 } return 0; // finally!!!
}
于 2015-11-03T14:39:41.913 回答
0

随着 x 的增加,sin(x) 和 cos(x) 的泰勒展开需要更长的时间来收敛。但由于这些是周期函数,因此您实际上不需要为 0-90° 范围之外的值扩展系列。

对于此范围之外的 x 值,请使用以下标识:

sin(x) = -sin(x+180°) = -sin(-x) = sin(180°-x)
cos(x) = -cos(x+180°) = cos(-x) = -cos(180°-x)

例如,sin(175°) = sin(5°),cos(-120°) = -cos(60°)

于 2015-10-30T09:45:44.390 回答
0

根据其定义,泰勒级数是无限级数的总和。

因此,泰勒有限展开只是真实结果的近似:随着项数的增加,这种近似的准确性会提高。

如果有足够的项,则在某个点的近似误差变得不明显。但是,如果您尝试减少项数,则近似误差会增加并且可以检测到。

在您的情况下,近似误差低于 = 15 的检测阈值,但在= 10 或更NUMBER_OF_TERMS小时变得明显。NUMBER_OF_TERMS

于 2015-10-30T09:38:24.640 回答