Loading your workspace…
Loading your workspace…
Approximate sin(x) and cos(x) with Taylor series, combine them into sin(x)/cos(x), and compare each result with the library functions in math.h.
#include <stdio.h>
#include <math.h>
#define TERMS 15
#define ZERO_TOLERANCE 1e-12
double taylor_sin(double x) {
double term = x;
double sum = x;
int k;
for (k = 1; k <= TERMS; k++) {
term *= -x * x / ((2 * k) * (2 * k + 1));
sum += term;
}
return sum;
}
double taylor_cos(double x) {
double term = 1.0;
double sum = 1.0;
int k;
for (k = 1; k <= TERMS; k++) {
term *= -x * x / ((2 * k - 1) * (2 * k));
sum += term;
}
return sum;
}
int main(void) {
double x, s, c, ratio_taylor, ratio_lib, diff;
printf("Enter angle x in radians:\n");
if (scanf("%lf", &x) != 1) {
printf("Error: invalid input\n");
return 1;
}
s = taylor_sin(x);
c = taylor_cos(x);
printf("%-26s: %.6f\n", "sin(x) by Taylor series", s);
printf("%-26s: %.6f\n", "sin(x) from math.h", sin(x));
printf("%-26s: %.6f\n", "cos(x) by Taylor series", c);
printf("%-26s: %.6f\n", "cos(x) from math.h", cos(x));
if (fabs(c) < ZERO_TOLERANCE) {
printf("sin(x)/cos(x) is undefined because cos(x) is zero\n");
return 0;
}
ratio_taylor = s / c;
ratio_lib = sin(x) / cos(x);
diff = fabs(ratio_taylor - ratio_lib);
printf("%-26s: %.6f\n", "sin(x)/cos(x) by Taylor", ratio_taylor);
printf("%-26s: %.6f\n", "sin(x)/cos(x) from math.h", ratio_lib);
if (diff < 1e-6) {
printf("Inference: the Taylor result agrees with math.h to 6 decimal places\n");
} else {
printf("Inference: the results differ by %.6f\n", diff);
}
return 0;
}
Input
0.5Output
Enter angle x in radians:
sin(x) by Taylor series : 0.479426
sin(x) from math.h : 0.479426
cos(x) by Taylor series : 0.877583
cos(x) from math.h : 0.877583
sin(x)/cos(x) by Taylor : 0.546302
sin(x)/cos(x) from math.h : 0.546302
Inference: the Taylor result agrees with math.h to 6 decimal placesInput
0Output
Enter angle x in radians:
sin(x) by Taylor series : 0.000000
sin(x) from math.h : 0.000000
cos(x) by Taylor series : 1.000000
cos(x) from math.h : 1.000000
sin(x)/cos(x) by Taylor : 0.000000
sin(x)/cos(x) from math.h : 0.000000
Inference: the Taylor result agrees with math.h to 6 decimal placesEach Taylor term is derived from the previous one by multiplying by -x² and dividing by the next two factorial factors. This avoids computing large factorials and powers separately, which would overflow quickly.
Fifteen terms are plenty for angles of a few radians, so the Taylor values match math.h to six decimal places. For large x the series converges more slowly, which is why the lab asks for an inference rather than an exact match.
Edit the program and press Run. It is free and needs no sign-in.
Copy a sample and paste it into the STDIN box in the editor before you press Run.
0.5
Expected output
Enter angle x in radians: sin(x) by Taylor series : 0.479426 sin(x) from math.h : 0.479426 cos(x) by Taylor series : 0.877583 cos(x) from math.h : 0.877583 sin(x)/cos(x) by Taylor : 0.546302 sin(x)/cos(x) from math.h : 0.546302 Inference: the Taylor result agrees with math.h to 6 decimal places
0
Expected output
Enter angle x in radians: sin(x) by Taylor series : 0.000000 sin(x) from math.h : 0.000000 cos(x) by Taylor series : 1.000000 cos(x) from math.h : 1.000000 sin(x)/cos(x) by Taylor : 0.000000 sin(x)/cos(x) from math.h : 0.000000 Inference: the Taylor result agrees with math.h to 6 decimal places
The Maclaurin series of sin is an odd function, so it contains only odd powers of x; cos is even and contains only even powers.
It avoids computing x to a large power and a large factorial separately, which could overflow.
cos(x) is zero there, so the ratio is undefined; the program reports this instead of dividing by zero.
Floating-point results rarely match exactly, so a small tolerance such as 1e-6 is the correct test.
It depends on x: the terms shrink quickly for small x, so the number of terms needed grows with the size of |x|.
Back to all VTU BPOPS103 lab programs.