在 C 中使用泰勒级数的自定义正弦函数(也许也是 C++)[关闭]

问题描述 投票:0回答:1

这是我为学校作业用 Tayilo 的序列计算正弦的一个小程序 我有。有人有更好的主意吗?我的意思是它有效,但还可以更好

#include <stdio.h>
#include <math.h>
int main(int argc, int **argv){
    system ("chcp 1253");
    int deg, i, a=(-1), flag=0;
    double pi=3.14159265359, x, sinx, o1, o2; //pi is rounded up to the last digit
    
    printf("Δώσε γωνία σε μοίρες από 0-2π (0-360):"); //translate: give angle in degrees
    scanf("%d",&deg);
    x=(pi/180)*deg; //apo moires se rad (metavlith x)
    o2=((x*x*x)/6)*a;
    sinx=x+o2;
    
    for(i=4; flag!=1; i+=2){
        o1=a*o2*((x*x)/(i*(i+1)));
        if (fabs(o2-o1)<=0.000001){
            flag=1;
        };
        sinx=sinx+o1;
        o2=o1;
    };
    
    printf("\nΤο ημίτονο του %d είναι: %f", deg, sinx); //the sine of %d is ...
    return 0;
};

在我的菜鸟眼中,代码没有任何问题,但我确信它可以改进。

c++ c trigonometry
1个回答
0
投票

有人有更好的主意吗?我的意思是它有效,但还可以更好

近似圆周率

“pi 向上舍入到最后一位数字”错误地表述了 最后一位数字。使用这样的舍入值没有任何优势。

double
通常具有 53 位精度。 pi 至少使用 17 位有效小数位。您的系统将尽其所能。

// double pi=3.14159265359
double pi=3.1415926535897932384626433832795

它的浮动

double
被编码为 floating 点,而不是 fixed 点。
fabs(o2-o1)<=0.000001
是对 fixed 点算法的有用比较。相反,终止条件应该接近从“浮动”角度结束的系列。 // fabs(o2-o1)<=0.000001 #define MY_EPSILON 0.000001 fabs(o2-o1)<= fabs(o1)*MY_EPSILON

我会使用更精细的 
epsilon

,也许是 1.0e-15,并避免使用赤裸裸的幻数。 同样,

"%f"

报告小数点后有固定位数。当正弦算法对于小角度非常有效时,此报告针对所有小角度为 0.000000。使用

"%g"
"%.15g"
了解更多详细信息。这里使用的
printf()
 precision
与上面使用的 epsilon 有关。

代码是从小项到大项计算

这比另一个方向稍好一些,但更难确定何时停止。

大值

当范围远离[-90...+90]度时,泰勒级数收敛缓慢。使用三角函数将角度调整为 [0...+/-45] 度。然后还编写一个

cosine()

例程。

将范围缩小为

弧度

是很棘手的,因为 pi 是一个无理数。因此,先减小角度,以度为单位。对于 fmod(),这通常是

精确
deg = fmod(deg, 360.0);

示例替代方案(未经测试,并且仍然缺乏除 [-360...+360] 之外的范围缩小 - 尚未完成的事情):

#include <math.h> double sine(double x_degrees) { static const double d2r = 3.1415926535897932384626433832795 / 180.0; // Bring x into the primary range double x_radians = fmod(x_degrees, 360.0) * d2r; double sum = 0.0; double x2 = x_radians * x_radians; double term = x_radians; for (unsigned i = 1; ; i++); double new_sum = sum + term; // If additional terms fail to change the sum, quit. if (new_sum == sum) { break; } sum = new_sum; term *= -x2 / ((2 * i) * (2 * i + 1)); } return sum; }

© www.soinside.com 2019 - 2024. All rights reserved.