#include "cpp_headers/fcpp.hh"

// Berechne die Determinante einer 2x2 Matrix mit doubles
double determinante_double(double a, double b, double c, double d) {
    return a*d - b*c;
}

// Berechne die Determinante einer 2x2 Matrix mit floats
float determinante(float a, float b, float c, float d) {
    return a*d - b*c;
}

// Teste die Assoziativitaet von floating point Zahlen
float testAssoziativitaet() {
    for (int n = 1; n <= 14; n++) {
        // (a+b)+c
        float vers1 = (pow(10, n) + -pow(10, n)) + pow(10,-n);
        // a+(b+c)
        float vers2 = pow(10, n) + (-pow(10, n) + pow(10,-n));
        print(n, vers1, vers2, 0);
    }
}

// Berechnet den effektiven Zinssatz mit floats
// z: Zinssatz, n: Abrechnungsvorgaenge
float zins(float z, int n) {
    return pow(1 + z/n, n) - 1;
}

// Berechnet den effektiven Zinssatz mit doubles
// z: Zinssatz, n: Abrechnungsvorgaenge
double zins(double z, int n) {
    return pow(1 + z/n, n) - 1;
}

// Vergleiche die Berechnung des effektiven Zinssatzes bei n Abrechnungsvorgaengen
// mit floats und doubles und vergleiche mit dem Grenzwert für n -> unendlich.
void compare(int n) {
    // Berechne effektiven Zins mit float
    float zf = zins(0.06, n);
    // Berechne die Differenz zu exp(z) - 1
    float difff = exp(0.06) - 1 - zf;
    // Berechne effektiven Zins mit double
    double zd = zins(0.06, n);
    // Berechne die Differenz zu exp(z) - 1
    double diffd = exp(0.06) - 1 - zd;
    // Gebe alles aus
    print("Abrechnungsvorgaenge:", n, 0);
    print("Zinssatz (float):", zf, 0);
    print("Abweichung von exp(z) - 1:", difff, 0);
    print("Zinssatz (double):", zd, 0);
    print("Abweichung von exp(z) - 1:", diffd, 0);
    print("");
}

int main() {
    // Determinantenberechnung (Aufgabe 1)
    print("det", determinante(100, 0.01, -0.01, 100), 0);
    print("double det", determinante_double(100, 0.01, -0.01, 100), 0);
    // Teste die Assoziativitaet (Aufgabe 1)
    testAssoziativitaet();

    // vergleiche fuer verschiedene Werte (Aufgabe 2)
    compare(1);
    compare(4);
    compare(12);
    compare(365);
    compare(365*24);
    compare(365*24*60);
    compare(365*24*60*2);
    compare(365*24*60*60);
}
