泰勒级数来计算余弦(得到余弦(90)的输出-0.000)

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

我为泰勒级数编写了以下函数以计算余弦。

double cosine(int x) {
    x %= 360; // make it less than 360
    double rad = x * (PI / 180);
    double cos = 0;

    int n;

    for(n = 0; n < TERMS; n++) { 
        cos += pow(-1, n) * pow(rad, 2 * n) / fact(2 * n);
    }
    return cos;
}

我的问题是,当我输入90时,我得到的答案是-0.000000。 (为什么我得到-0.000而不是0.000?)

有人可以解释为什么以及如何解决这个问题吗?我认为这是由于double的精度所致。这是main():

int main(void){
int y;
//scanf("%d",&y);
y=90;
printf("sine(%d)= %lf\n",y, sine(y));
printf("cosine(%d)= %lf\n",y, cosine(y));

return 0;
}
c precision trigonometry taylor-series
1个回答
2
投票

完全希望您无法获得带有浮点的anything的余弦的精确零输出,而不管您的计算方法有多好。这是浮点如何工作的基础。

余弦的数学零为pi / 2的奇数倍。由于pi是非理性的,因此无法完全表示为double(或任何浮点形式),并且可表示的最接近的相邻值之间的差至少为pi / 2倍DBL_EPSILON,大约为3e-16(或其他浮点类型的相应值)。对于pi / 2的奇数倍,您可能会“很幸运”并发现它确实非常接近两个邻居之一,但是平均而言,您会发现它大约1e-16。因此,您的输入是1e-16左右已经错误

现在,余弦在其零处具有斜率+1或-1,因此输出中的误差将与输入中的误差大致成比例。但是要获得精确的零,您需要的误差应小于可表示的最小非零双精度数,即2e-308左右。这比输入错误小了近300个数量级。

虽然您在理论上可以“幸运”,并且如果pi / 2确实非常接近最接近的可表示倍数,则有一些倍数,但将其建模为随机数的可能性从天文学角度来看很小。我相信甚至有证据表明,存在[[no double x,其中cos(x)的正确舍入值为正好为零。对于单精度(float),可以通过蛮力很容易地确定;对于double可能也是可行的,但是需要大量的计算。

关于printf为什么打印-0.000000的原因,仅是%f的默认值是小数点后6位,这远远不能看到第一个有效数字。使用%e%g,还可以选择使用一个较大的精度修饰符,它将为您显示所获得结果的近似值,该结果实际上仍具有一定的意义,并让您知道结果是否良好。
© www.soinside.com 2019 - 2024. All rights reserved.