cmathformulataylor-series

Taylor series (mclauren), after 9 or 11, compiler writes;


My formula for sin(x) in taylor series(picture under the code). In general if i enter Start 1 and end 20 with step 2, console output '-nan' after x = 9; sin(X) and Taylor should be the same;, for example:

x = 9; sin(x) = 0.412118; taylor = 0.412118

x = 11; sin(x) = -0.99999; taylor -0.999976;

x = 13; sin(x) = 0.420167; taylor = -nan;

like this all the time; i need some help; its for my laboratory

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

int main(void) {
    float a, b, left, right, eps = 0.00001, step, x, add = 1, chis, znam, fact, sum = 0, delta;
    printf("Plese enter your start: ");
    scanf("%f", &a);
    printf("Your end: ");
    scanf("%f", &b);
    printf("and step: ");
    scanf("%f", &step);

    if (b < a || a < eps) {
        printf("Your inputs aren't correct");
        return -1;
    }

    printf("\tX\t           sin(x)\tTaylor\t   Delta\n");
    for (x = a; x < b; x += step) {

        printf("    x = %9f\t", x);
        left = sin(x);
        printf("%9f", left);

        chis = -x;
        znam = 1;

        sum = 0;
        add = 1;
        fact = 1;
        while (fabs(add) > eps) {
            add = -1 * chis / znam;
            sum += add;
            chis *= -1 * (x * x);
            fact++;
            znam *= fact * (fact + 1);
            fact++;

        }
        printf("    %9f    ", sum);
        printf("%e\n", fabs(left - sum));
    }
}

enter image description here


Solution

  • znam is +inf because fact is 35, 35! is over 2^131, and the maximum positive single-precision floating pointer number is hair less than 2^128.

    You could buy yourself some time by switching to double-precision floating point numbers. But that's not the right solution.

    Currently, you are calculating the 17th term as

    -1 * x^35 / 35!
    

    But you could also calculate it as follows[1]:

    previous_term * -1 * x / 34 * x / 35
    

    This avoids very large intermediary numbers.


    1. Math:

        -1 * x^35 / 35!
      = ( +1 * -1 ) * ( x^33 * x * x ) / ( 35 * 34 * 33! )
      = +1 * -1 * x^33 * x * x / 35 / 34 / 33!
      = ( +1 * x^33 / 33! ) * -1 * x * x / 35 / 34
      = previous_term * -1 * x / 34 * x / 35