此泰勒级数代码不适用于 n=1 或 0 以外的任何值。为什么?
This code of taylor series doesn't work for n= 1 or anything other than 0. Why?
首先告诉你,我正在学习编程
今天尝试用泰勒级数求余弦的近似值。当我输入 n=0 时,我的代码给出了 1 的正确结果。但是当我输入 n=1 或其他任何内容时,我的代码没有给出正确的结果。
我无法理解问题出在哪里。有人可以帮忙吗?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
float xnot = atof(argv[1]);
float n = atof(argv[2]);
float cosine = cos(xnot*(3.14159265/180));
float result;
printf("%.4f\n", cosine);
float min;
float d, c, b;
c = 1;
d = 2 * n;
for(b = 1; b <= d; b++){
c = c * b; /*value of the factorial is in c*/
}
c = c;
float power;
power = pow((-1), n);
xnot = pow(xnot, 2*n);
for(min = 0; min <= n; min++)
{
result += ((power * xnot) / c);
}
printf("%.4f", result);
}
实施泰勒级数时,您必须为 'n' 的每个值重新计算项的值。在这里,您似乎已经为 n
的最大值计算了 -1^n
的值(如 xnot
),然后您只需在每次迭代中乘以该值。那是错误的。 x^2n / (2n)!
的值相同 - 您必须在递增时为 n
的每个值重新计算它,然后对这些值求和。
祝你好运。
在使用泰勒级数计算正弦或余弦时,您还需要考虑 angular 象限,以最大限度地减少误差增长。以下是一个简短的例子:
#define TSLIM 20 /* Series Limit (no. of terms) */
...
/** cos with taylor series expansion to n = TSLIM
* (no function reliance, quadrants handled)
*/
double cosenfq (const double deg)
{
double fp = deg - (int64_t)deg, /* save fractional part of deg */
qdeg = (int64_t)deg % 360, /* get equivalent 0-359 deg angle */
rad, cose_deg = 1.0; /* radians, cose_deg */
int pos_quad = 1, /* positive quadrant flag 1,4 */
sign = -1; /* taylor series term sign */
qdeg += fp; /* add fractional part back to angle */
/* get equivalent 0-90 degree angle, set pos_quad flag */
if (90 < qdeg && qdeg <= 180) { /* in 2nd quadrant */
qdeg = 180 - qdeg;
pos_quad = 0;
}
else if (180 < qdeg && qdeg <= 270) { /* in 3rd quadrant */
qdeg = qdeg - 180;
pos_quad = 0;
}
else if (270 < qdeg && qdeg <= 360) /* in 4th quadrant */
qdeg = 360 - qdeg;
rad = qdeg * M_PI / 180.0; /* convert to radians */
/* compute Taylor-Series expansion for sine for TSLIM / 2 terms */
for (int n = 2; n < TSLIM; n += 2, sign *= -1) {
double p = rad;
uint64_t f = n;
for (int i = 1; i < n; i++) /* pow */
p *= rad;
for (int i = 1; i < n; i++) /* nfact */
f *= i;
cose_deg += sign * p / f; /* Taylor-series term */
}
return pos_quad ? cose_deg : -cose_deg;
}
在 20 个术语的限制下,最大误差约为 1.2E-15
(与 math.h cos()
相比)
您需要重做 for 循环内的所有计算。尽可能多地保留原始代码,它可能是这样的:
int n = atoi(argv[2]); // n is an integer
...
...
float result = 1; // The first term (n=0) gives 1
for(int i = 1; i <= n; i++) // Start the loop from 1
{
float d, c, b;
c = 1;
d = 2 * i; // Use i instead of n
for(b = 1; b <= d; b++){
c = c * b; /*value of the factorial is in c*/
}
float power;
power = pow((-1), i); // Use i instead of n
xnot = pow(xnot, 2*i); // Use i instead of n
result += ((power * xnot) / c);
}
代码可以优化 - 无论是性能还是精度 - 但如前所述,我尽量使其接近您的原始代码。
首先告诉你,我正在学习编程
今天尝试用泰勒级数求余弦的近似值。当我输入 n=0 时,我的代码给出了 1 的正确结果。但是当我输入 n=1 或其他任何内容时,我的代码没有给出正确的结果。
我无法理解问题出在哪里。有人可以帮忙吗?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
float xnot = atof(argv[1]);
float n = atof(argv[2]);
float cosine = cos(xnot*(3.14159265/180));
float result;
printf("%.4f\n", cosine);
float min;
float d, c, b;
c = 1;
d = 2 * n;
for(b = 1; b <= d; b++){
c = c * b; /*value of the factorial is in c*/
}
c = c;
float power;
power = pow((-1), n);
xnot = pow(xnot, 2*n);
for(min = 0; min <= n; min++)
{
result += ((power * xnot) / c);
}
printf("%.4f", result);
}
实施泰勒级数时,您必须为 'n' 的每个值重新计算项的值。在这里,您似乎已经为 n
的最大值计算了 -1^n
的值(如 xnot
),然后您只需在每次迭代中乘以该值。那是错误的。 x^2n / (2n)!
的值相同 - 您必须在递增时为 n
的每个值重新计算它,然后对这些值求和。
祝你好运。
在使用泰勒级数计算正弦或余弦时,您还需要考虑 angular 象限,以最大限度地减少误差增长。以下是一个简短的例子:
#define TSLIM 20 /* Series Limit (no. of terms) */
...
/** cos with taylor series expansion to n = TSLIM
* (no function reliance, quadrants handled)
*/
double cosenfq (const double deg)
{
double fp = deg - (int64_t)deg, /* save fractional part of deg */
qdeg = (int64_t)deg % 360, /* get equivalent 0-359 deg angle */
rad, cose_deg = 1.0; /* radians, cose_deg */
int pos_quad = 1, /* positive quadrant flag 1,4 */
sign = -1; /* taylor series term sign */
qdeg += fp; /* add fractional part back to angle */
/* get equivalent 0-90 degree angle, set pos_quad flag */
if (90 < qdeg && qdeg <= 180) { /* in 2nd quadrant */
qdeg = 180 - qdeg;
pos_quad = 0;
}
else if (180 < qdeg && qdeg <= 270) { /* in 3rd quadrant */
qdeg = qdeg - 180;
pos_quad = 0;
}
else if (270 < qdeg && qdeg <= 360) /* in 4th quadrant */
qdeg = 360 - qdeg;
rad = qdeg * M_PI / 180.0; /* convert to radians */
/* compute Taylor-Series expansion for sine for TSLIM / 2 terms */
for (int n = 2; n < TSLIM; n += 2, sign *= -1) {
double p = rad;
uint64_t f = n;
for (int i = 1; i < n; i++) /* pow */
p *= rad;
for (int i = 1; i < n; i++) /* nfact */
f *= i;
cose_deg += sign * p / f; /* Taylor-series term */
}
return pos_quad ? cose_deg : -cose_deg;
}
在 20 个术语的限制下,最大误差约为 1.2E-15
(与 math.h cos()
相比)
您需要重做 for 循环内的所有计算。尽可能多地保留原始代码,它可能是这样的:
int n = atoi(argv[2]); // n is an integer
...
...
float result = 1; // The first term (n=0) gives 1
for(int i = 1; i <= n; i++) // Start the loop from 1
{
float d, c, b;
c = 1;
d = 2 * i; // Use i instead of n
for(b = 1; b <= d; b++){
c = c * b; /*value of the factorial is in c*/
}
float power;
power = pow((-1), i); // Use i instead of n
xnot = pow(xnot, 2*i); // Use i instead of n
result += ((power * xnot) / c);
}
代码可以优化 - 无论是性能还是精度 - 但如前所述,我尽量使其接近您的原始代码。