1

We are doing C Programming in school and we have to calculate the cosine of a number with use of the "Taylor series" (https://en.wikipedia.org/wiki/Taylor_series). I know C programming but that what we have to do has not really much to do with programming itself more than being good in math.

If you put in your calculator cos(50) it's 0.6427.... That's what we have to do in C. There is the cos() function in math.h but that's not actually the cosine. I am overwhelmed with this and don't really know what we have to do. It should look something like this:

#include <stdio.h>
#include <conio.h>
#include <math.h> 

int fac(int n);
double meincosinus(double x);

void main() {
    double x;
    double y;
    int i;

    printf("geben sie eine zahl ein\n");

    scanf_s("%lf", &x);
    
    y = meincosinus(x);

    printf_s("cos(%lf)=%lf\n", x, y);

    y = sin(x);
    
    printf_s("cos(%lf)=%lf\n", x, y);

    scanf_s("%d", &i);
    printf_s("%d\n", i);
    
    _getch();
}

int fac(int n) {
    int prod = 1; 
    int i;

    for (i = 1; i <= n; i++)
    { 
        prod *= i; 
    } 

    return prod;
}

double meincosinus(double x)
{
    double erg = 0;
    int n;

    for (n = 0; n <= x; n++)
    {
        x = fac(n);
        erg += pow(-1, n) * pow(x, (2 * n)) / fac(2 * n);
    }

    return erg;
}

This code runs but the output is wrong.

Rogue
  • 11,105
  • 5
  • 45
  • 71
20maty
  • 131
  • 1
  • 5
  • 5
    Little off-topic (since you need to do it with a Taylor series anyhow): When you say it's "not actually the cosine", what do you mean? It's `cos(x)`, with `x` in radians. – Rogue Oct 06 '22 at 20:41
  • 1
    Re "There is the cos() function in math.h but that's not actually the cosine" Can you clarify what you mean here? `cos()` computes an approximation to the mathematical function, but in most modern implementations that approximation is accurate to almost machine precision. So for all practical purposes, *it does* compute the cosine. – njuffa Oct 06 '22 at 20:43
  • 2
    `cos(50)` does not work because you are providing the argument in degrees while the function expects radians. Try passing `0.872665` which is the equivalent in radians for 50degrees. – Davide Spataro Oct 06 '22 at 20:43
  • If your angle measurements are in degrees, you can multiply by `180.0/3.14159` to get radians and then pass to the `cos()` function – Willis Hershey Oct 06 '22 at 20:45
  • 5
    @WillisHershey: You should use `180./M_PI`, instead of truncating PI to merely 6 significant digits. – abelenky Oct 06 '22 at 20:47
  • 2
    When calculating a Taylor series, the angle needs to be in radians. If your input is in degrees, then you need to convert to radians using the formula `x_radians = x_degrees * M_PI / 180.0;` The definition for `M_PI` should be in ``. If `` doesn't define `M_PI`, then you'll have to define it yourself with `#define M_PI 3.14159265358979323846264338327950288` – user3386109 Oct 06 '22 at 20:57
  • Ok thank you guys. Radiants was a good hint. But i didnt make it word. Could someboady please answer the post with a working C Code where you input a value and get the cosinus out of it. Thanks – 20maty Oct 06 '22 at 21:10
  • @20maty the output from math.h's `cos` function _is_ correct, but you may have a mistake in your usage of it. I would compare the output of your taylor series function with the output of `cos(x)` to determine where things aren't lining up. It looks like you were planning to do this, but you used `sin` (**not** `cos`!!) in your comparison. – Rogue Oct 06 '22 at 21:17
  • 1
    @20maty The basics of a Taylor series are something you would normally pick up in high school calculus. Evaluating a Taylor series on a computer certainly involves math, but it is more of a Computer Science discipline than a Math discipline. But it's not system programming. It's more of a Numerical Analysis problem. I think most implementations tweak the Taylor series a little. Also, for periodic functions like sine and cosine, you need to reduce the range to -pi...pi (for sine) or 0...2pi (for cosine). They may even reduce it further, then adjust the result. – Tom Karzes Oct 06 '22 at 21:19
  • Note that in MSVC you have to `#define _USE_MATH_DEFINES` before `#include ` to enable `M_PI`. – Weather Vane Oct 06 '22 at 22:34
  • 1. if I see it right your `meincosinus` loop is simply wrong, the loop should go to some constant integer number iterations 2. why `pow`? see [example how to avoid it](https://stackoverflow.com/a/73258767/2521214) 3. use angle in radians do not expect that taylor series works with degrees – Spektre Oct 07 '22 at 06:28

1 Answers1

1

Not an answer (but, well, I am a teacher myself, I am not gonna make your homework :)). But a few questions you should ask yourself and that might help you

  1. Why are you comparing your Taylor computation of cosinus with the "real" sinus? Shouldn't y=sin(x) be y=cos(x), for a pertinent comparison?

  2. why are you doing this: x = fac(n);? You are overwriting your x argument to "meinconsinus". You can't expect meincosinus(50) to really compute cos(50) if the first thing you do is overwriting that "50" with something else (namely n!).

  3. also, why this for (n = 0; n <= x; n++). You know the Taylor formula better that I do (since you are studying it right now). It sure not supposed to stop after x iterations. x is rarely even an integer. It is supposed to be very small anyway. And could even be negative. So, question you've to ask yourself is, how many iterations (up to which term of the series) you want to compute. It is a rather arbitrary choice, since from Taylor point of view, answer is ∞. But on a computer, after a while it is no use to add extremely small numbers

  4. Since I am mentioning the fact that x is supposed to be small: you can't compute cos(50) that way with a Taylor formula. You could compute cos(0.1) or even cos(1) maybe, with enough iterations. But 50 is not a small enough number. Plus, 50ⁿ will be very quickly out of control in your loop. If you really want meincosinus to be able to handle any number, you have first to reduce x, using trigonometric rules: cos(x)=cos(x)-2π; cos(x)=-cos(x); cos(x)=sin(π/2-x); ... There are some better rules, but with those simple ones, you can have x in [0,π/4]. Since π/4<1, at least you don't have an explosive xⁿ.

  5. Also, but that is an optimization, you don't really need to compute neither (-1)ⁿ with pow (just alternate a int sign variable, between -1 and 1 at each iteration), nor x²ⁿ (just multiply a double x2n=1 by x*x each iteration), nor fac(2n) (just multiply a f=1 variable by (n-1)×n, being careful with 0 case, at each iteration.

chrslg
  • 9,023
  • 5
  • 17
  • 31
  • Just to note from the above comments, 1) appears to be a typo, and 4) is due to OP using degrees instead of radians. – Rogue Oct 06 '22 at 21:20
  • Noted for 1. But for 4, nevertheless, it wouldn't work with any x big enough. And nothing says that it is not supposed to be use with 50 radians. Or even just 2. Taylor is made for small values of x. – chrslg Oct 06 '22 at 21:30