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

struct nb{ 
    double x;
    struct nb *suivant;
};
// Question 2
int epsilon() {
    int n = 1;
    while (1 + pow(2, -n) != 1){
        n++;
    }
    return (n - 1);
}
// Question 3 (ou en itératif)
double u(int n){
    if (n == 0) return 2;
    if (n == 1) return -4;
    return 111 - 1130 / u(n - 1) + 3000 / (u(n - 1) * u(n - 2));
}
// Question 5 (pas en récursif (debordement de pile) : la liste est trop longue)
double somme(struct nb *liste) {
    double s = 0.;
    while (liste != NULL) {
        s = s + liste->x;
        liste = liste->suivant;
    }
    return s;
}
// Pour le test de somme sans fuite mémoire
// Deviendra inutile puisque la liste en entrée sera détruite via somme2
void libere_liste(struct nb *liste) {
    if (liste != NULL) {
        libere_liste(liste->suivant);
        free(liste);
    }
}
// Question 6
struct nb* insere(struct nb* val, struct nb* liste){
    // insere val dans la liste triée
    if (liste == NULL || val->x <= liste->x){
        val->suivant = liste;
        return val;
    } else {
        liste->suivant = insere(val, liste->suivant);
        return liste;
    }
}
double somme2(struct nb *tab) {
    // on suppose que tab est triée par ordre croissant et est non vide
    if (tab == NULL) return 0.0; // liste vide
    while (tab->suivant != NULL) {
        struct nb* premier = tab;
        struct nb* deuxieme = tab->suivant;
        struct nb* fin = tab->suivant->suivant;
        deuxieme->x += premier->x;
        free(premier);
        tab = insere(deuxieme, fin);
    }
    return tab->x; // un seul élément
}
int main() {
    double a = 2e65;
    double b = -2e65;
    double c = 1.0;
    printf("\n Question 1\n");
    // Calcul et affichage de (a+b)+c et a+(b+c)
    printf("(a+b)+c = %f\n", (a + b) + c);
    printf("a+(b+c) = %f\n", a + (b + c));

    printf("\n epsilon machine %i\n", epsilon());

    printf("\n Question 4\n");
    for (int i = 0; i < 22; i++) {
        printf("u_%d = %lf\n", i, u(i));
    }

    printf("\n Question 5-6\n");
    // Test des sommes
    // l est destinée à contenir la somme des 1/i pour i = 1 .. 10^5 dans l'ordre décroissant.
    struct nb *l = malloc(sizeof(struct nb));

    l->x = 1. / (pow(10, 5));
    l->suivant = NULL;

    struct nb *temp = l;

    for (int i = pow(10, 5) - 1; i > 0; i = i - 1) {
        struct nb *n = malloc(sizeof(struct nb));
        n->x = 1. / (float)i;
        n->suivant = NULL;
        temp->suivant = n;
        temp = temp->suivant;
    }

    printf("\n somme  %.15lf\n", somme(l));
    printf("\n somme  %.15lf\n ",somme2(l));
    // libere_liste(l);
    return 0;
}