Program liczący funkcję a^x szeregiem Taylora

2

Mam napisać program który dla funkcji a^x korzystając z Taylora liczy sumę szeregu w określonym przedziale. Program działa ale tylko do pierwszej iteracji pętli i nie działa określenie czy osiagnieto dokładność czy nie. Jakby ktoś potrafił pomoc to będę wdzięczny.

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

long double oblicz_sume_szeregu(long double z, long double x, int n, int M, long double epsilon, int* liczba_wyrazow)
{
    long double suma = 1; 
    long double p = 1;    
    long double f = 1;
    
    for (int i = 1; i <= M; i++)
    {
      
        p = (pow(x,i))*(pow(log(z),i));
        f *= i;
        long double d = p / f;
        suma += d;

        if (i <= M && epsilon >= d)
        {
            *liczba_wyrazow = i;
            
            break;
        }
        else if (i <= M && d > epsilon)
        {
            *liczba_wyrazow = i;
            
            break;
        }
        else if (M < i && epsilon >= d)
        {
            *liczba_wyrazow = M;
           
            break;
        }
        else if (M < i && d > epsilon)
        {
            *liczba_wyrazow = M;
            
            break;
        }
        
        
    }

    return suma;
}

int main()
{
    long double z, a, b, epsilon;
    int n, M;

    printf("Program liczy sumę szeregu funkcji y=a^x z pomocą szeregu Taylora w przedziale (a,b) dla |x|<∞.\n Zostaniesz poproszona/y o podanie podstawy funkcji, przedziału dla (a,b) w ktorych znajduje się x,\n dzielnika przedziału określającego ilość x z ktorych będzie liczona suma szeregu,\n ε określającego dokładność obliczeń sumy oraz maksymalną ilość M wyrazow w szeregach sumy.\n ");
    printf("Podaj wartość a (podstawa funkcji) (liczba rzeczywista): ");
    int status_z = scanf("%Lf", &z);
    while (status_z != 1 || getchar() != '\n')
    {
        printf("Nieprawidłowa wartość, a musi byc liczbą rzeczywistą. Podaj ponownie: ");
        while (getchar() != '\n');  
        status_z = scanf("%Lf", &z);
    }
    printf("Podaj przedział wartości funkcji (a, b):\n");
    printf("a = ");
    int status_a = scanf("%Lf", &a);
    while (status_a != 1 || getchar() != '\n')
    {
        printf("Nieprawidlowa wartość, a musi być liczbą rzeczywistą. Podaj ponownie: ");
        while (getchar() != '\n');  
        status_a = scanf("%Lf", &a);
    }
    printf("b = ");
    int status_b = scanf("%Lf", &b);
    while (status_b != 1 || getchar() != '\n')
    {
        printf("Nieprawidlowa wartość, b musi byc liczbą rzeczywistą. Podaj ponownie: ");
        while (getchar() != '\n');  
        status_b = scanf("%Lf", &b);
    }
    printf("Podaj ilość części na jaką przedział (a,b) ma zostać podzielony (n): ");
    int status_n = scanf("%d", &n);
    while (status_n != 1 || getchar() != '\n')
    {
        printf("Nieprawidlowa wartość. n musi być liczbą calkowitą. Podaj ponownie: ");
        while (getchar() != '\n');  
        status_n = scanf("%d", &n);
    }

    printf("Podaj dokladność epsilonu: ");
    int status_epsilon = scanf("%Lf", &epsilon);
    while (status_epsilon != 1 || getchar() != '\n')
    {
        printf("Nieprawidłowa wartość. Epsilon musi byc liczba rzeczywistą. Podaj ponownie: ");
        while (getchar() != '\n');  
        status_epsilon = scanf("%Lf", &epsilon);
    }

   printf("Podaj ilość wyrazow ciągu ktore mają być zsumowane (M) (liczba naturalna): ");
    int status_M = scanf("%d", &M);
    while (status_M != 1 || M <= 0)
    {
        printf("Nieprawidlowa wartość. M musi byc liczbą naturalną. Podaj ponownie: ");
        while (getchar() != '\n'); 
        status_M = scanf("%d", &M);
    }

   printf("%-60s%-60s%-60s%-60s%-60s\n", "x", "f_szereg(x)", "f_ścisłe(x)", "liczba wyrazow szeregu", "warunek stopu");
    
    long double d = 0.0;
    long double h = (b - a) / n;
    for (long double x = a; x <= b; x += h)
    {
        int liczba_wyrazow;
        long double wynik = oblicz_sume_szeregu(z, x, n, M, epsilon, &liczba_wyrazow);
        if (epsilon >= d)
        printf("%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), liczba_wyrazow, "Osiagnieto dokladnosc");
    else if (d > epsilon)
        printf("%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), liczba_wyrazow, "Nie osiagnieto dokladnosci");
    }

    FILE *plik = fopen("wyniki.txt", "w");

    if (plik == NULL)
    {
        fprintf(stderr, "Nie można otworzyć pliku do zapisu.\n");
        return 1;
    }

    fprintf(plik, "%-60s%-60s%-60s%-60s%-60s\n", "x", "f_szereg(x)", "f_ścisłe(x)", "liczba wyrazow szeregu", "warunek stopu");
    d = 0.0;
    h = (b - a) / n;
    for (long double x = a; x <= b; x += h)
    {
        int liczba_wyrazow;
        long double wynik = oblicz_sume_szeregu(z, x, n, M, epsilon, &liczba_wyrazow);
        if (liczba_wyrazow <= M && epsilon > d)
        fprintf(plik, "%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), liczba_wyrazow, "Osiagnieto dokladnosc");
    else if (liczba_wyrazow <= M && d > epsilon)
        fprintf(plik, "%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), liczba_wyrazow, "Nie osiagnieto dokladnosci");
    }
    fclose(plik);
    printf("Wyniki zostały zapisane do pliku 'wyniki.txt'.\n");
    return 0;
}
2

Poświęciłem temu cały wieczór ale znalazłem odpowiedzi na mój problem więc się dzielę dla potomnych bo na pewno kiedyś spotkają się z takim problemem.

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

#include <float.h>

long double globalna_d;
          
int globalna_liczba_wyrazow = 1;
      
long double oblicz_sume_szeregu(long double z, long double x, int n, int M, long double epsilon, int* liczba_wyrazow){

long double suma = 1; 

long double p = 1;    

long double f = 1;

long double d = 0.0;

int i = 1;

for (i = 1; i < M; i++){
    p = (pow(x, i)) * (pow(log(z), i));
    f *= i;
    d = p / f;
    suma += d;
    
if (i <= M && epsilon >= fabs(d)){
        *liczba_wyrazow = i;
        break;
    }
    else if (i <= M && fabs(d) > epsilon){
        *liczba_wyrazow = i;
    }
    else if (M <= i && epsilon >= fabs(d)){
        *liczba_wyrazow = M;
        break;
    }
    else if (M <= i && fabs(d) >= epsilon){
        *liczba_wyrazow = M;
        break;
    }
}
globalna_d = fabs(d);
globalna_liczba_wyrazow = *liczba_wyrazow;

return suma;
}

    int main(){
long double z, a, b, epsilon;
int n, M;

printf("Program liczy sumę szeregu funkcji y=a^x z pomocą szeregu Taylora w przedziale (a,b) dla |x|<∞.\n Zostaniesz poproszona/y o podanie podstawy funkcji, przedziału dla (a,b) w ktorych znajduje się x,\n dzielnika przedziału określającego ilość x z których będzie liczona suma szeregu,\n ε określającego dokładność obliczeń sumy oraz maksymalną ilość M wyrazow w szeregach sumy.\n ");

printf("Podaj wartość a (podstawa funkcji) (liczba rzeczywista i większa od 0): ");
int status_z = scanf("%Lf", &z);
while (status_z != 1 || z < 0 ||getchar() != '\n'){
    printf("Nieprawidłowa wartość, a musi być liczbą rzeczywistą większą od 0. Podaj ponownie: ");
    while (getchar() != '\n');
    status_z = scanf("%Lf", &z);
    }

printf("Podaj przedział wartości funkcji (a, b):\n");
printf("a = ");
int status_a = scanf("%Lf", &a);
while (status_a != 1 || getchar() != '\n'){   
    printf("Nieprawidłowa wartość, a musi być liczbą rzeczywistą. Podaj ponownie: ");
    while (getchar() != '\n');
    status_a = scanf("%Lf", &a);
    }

printf("b = ");
int status_b = scanf("%Lf", &b);
while (status_b != 1 || getchar() != '\n'){
    printf("Nieprawidłowa wartość, b musi być liczbą rzeczywistą. Podaj ponownie: ");
    while (getchar() != '\n');
    status_b = scanf("%Lf", &b);
    }

printf("Podaj ilość części na jaką przedział (a,b) ma zostać podzielony (n): ");
int status_n = scanf("%d", &n);
while (status_n != 1 || getchar() != '\n'){
    printf("Nieprawidłowa wartość. n musi być liczbą całkowitą. Podaj ponownie: ");
    while (getchar() != '\n');
    status_n = scanf("%d", &n);
    }

printf("Podaj dokładność epsilonu: ");
int status_epsilon = scanf("%Lf", &epsilon);
while (status_epsilon != 1 || getchar() != '\n'){
    printf("Nieprawidłowa wartość. Epsilon musi być liczbą rzeczywistą. Podaj ponownie: ");
    while (getchar() != '\n');
    status_epsilon = scanf("%Lf", &epsilon);
    }

printf("Podaj ilość wyrazów ciągu które mają być zsumowane (M) (liczba naturalna): ");
int status_M = scanf("%d", &M);
while (status_M != 1 || M <= 0){
    printf("Nieprawidłowa wartość. M musi być liczbą naturalną. Podaj ponownie: ");
    while (getchar() != '\n');
    status_M = scanf("%d", &M);
    }

printf("%-60s%-60s%-60s%-60s%-60s\n", "x", "f_szereg(x)", "f_ścisłe(x)", "liczba wyrazów szeregu", "warunek stopu");

long double d = 0.0;
long double h = (b - a) / n;
for (long double x = a; x <= b; x += h){
    int liczba_wyrazow;
    long double wynik = oblicz_sume_szeregu(z, x, n, M, epsilon, &liczba_wyrazow);
    
    if (liczba_wyrazow <= M && epsilon >= globalna_d)
        printf("%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Osiągnięto dokładność");
    else if (liczba_wyrazow <= M && globalna_d > epsilon)
        printf("%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Nie osiągnięto dokładności");
    else if (M < liczba_wyrazow && epsilon >= globalna_d)
        printf("%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Nie osiągnięto dokładności");
    else if (M < liczba_wyrazow && globalna_d >= epsilon)
        printf("%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Nie osiągnięto dokładności");        
        }

FILE* plik = fopen("wyniki.txt", "w");

if (plik == NULL){
    fprintf(stderr, "Nie można otworzyć pliku do zapisu.\n");
    return 1;
    }

fprintf(plik, "%-60s%-60s%-60s%-60s%-60s\n", "x", "f_szereg(x)", "f_ścisłe(x)", "liczba wyrazów szeregu", "warunek stopu");
d = 0.0;
h = (b - a) / n;
for (long double x = a; x <= b; x += h){
    int liczba_wyrazow;
    long double wynik = oblicz_sume_szeregu(z, x, n, M, epsilon, &liczba_wyrazow);

    if (liczba_wyrazow <= M && epsilon >= globalna_d)
        fprintf(plik, "%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Osiągnięto dokładność");
    else if (liczba_wyrazow <= M && globalna_d > epsilon)
        fprintf(plik, "%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Nie osiągnięto dokładności");
    else if (M < liczba_wyrazow && epsilon >= globalna_d)
        fprintf(plik, "%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Nie osiągnięto dokładności");
    else if (M < liczba_wyrazow && globalna_d >= epsilon)
        fprintf(plik, "%-60.2Lf%-60.30Lf%-60.30Lf%-60d%-60s\n", x, wynik, pow(z, x), globalna_liczba_wyrazow, "Nie osiągnięto dokładności");
        }
        fclose(plik);
        printf("Wyniki zostały zapisane do pliku 'wyniki.txt'.\n");
return 0;}

1 użytkowników online, w tym zalogowanych: 0, gości: 1