This is my task:
Write a C function to evaluate the series // cos(x) = x-(x2 /2!)+(x4 /4!)-(x6 /6!)+... etc. Variable realNuber use radians instead of degrees
I lose precision, but I don't understand where. The answer with realNumber = 60 must be 0.500, but I've 0.501. Please help.
#include "stdio.h"
#include "inttypes.h"
double power(float N, uint32_t P){
double buffer = 1;
for (int i = 0; i < P; ++i) {
buffer *= N;
}
return buffer;
}
float factorial(float number){
float result = number;
if (number == 0) {
return 0;
}
for (int i = 0; i < number - 1; ++i) {
result *= i + 1;
}
return result;
}
float cos(float x){
float result = x * (3.14159265359 / 180.);
float polar = -1;
for (int i = 2; i < 10; i += 2) {
result += power(result, i) / factorial(i) * polar;
polar *= -1;
}
return result;
}
int main(void){
float realNumber = 0;
float result = 0;
scanf("%f", &realNumber);
result = cos(realNumber);
printf("%.13f", result);
}
I tried making changes in function cos(); maybe the problem is in a different place?
You originally wrote:
Write a C function to evaluate the series // cos(x) = x-(x2 /2!)+(x4 /4!)-(x6 /6!)
But that is NOT the Taylor series for cos.
The proper formula is:
(Note the 1
in the first term not an x
)
Source
With a correction to your Taylor series, and some other fix up, I got:
Success #stdin #stdout 0s 5392KB
0.4999999701977
My Code:
#include "stdio.h"
#include "inttypes.h"
// No Changes
double power(float N, uint32_t P){
double buffer = 1;
for (int i = 0; i < P; ++i) {
buffer *= N;
}
return buffer;
}
// No Changes
float factorial(float number){
float result = number;
if (number == 0) {
return 0;
}
for (int i = 0; i < number - 1; ++i) {
result *= i + 1;
}
return result;
}
// Minor changes, explained in comments
float cos(float x){
x = x * (3.14159265359 / 180.); // Convert Degrees to Radians
float result = 1; // Taylor series starts with 1, not with x !!!
float polar = -1;
for (int i = 2; i <= 10; i += 2) {
result += power(x, i) / factorial(i) * polar;
polar *= -1;
}
return result;
}
// Skipped the scanf in favor of hard-coded value, for simplicity.
int main(void){
float realNumber = 60;
float result = 0;
result = cos(realNumber);
printf("%.13f", result);
}
When I re-wrote the cos function to eliminate using power and factorial functions, I got this:
double cos(float x){
x = x * (3.14159265359 / 180.); // Convert Degrees to Radians
double num = 1; // Numerator of the fraction (x^2, x^4...)
int sgn = +1; // Sign, alternating -1, +1
uint64_t den = 1; // Denominator: Factorials, 2!, 4!, 6!...
float ans = 1; // Accumulated answer
for (int i = 2; i <= 10; i += 2) {
num *= x*x;
den *= i*i-i;
sgn *= -1;
ans += num / den * sgn;
}
return ans;
}