//
//  cmath.c
//  CMath
//
//  Created by TheAlgorithm476 on 28/03/2025.
//

#include <stdint.h>
#include "add_nums.h"
#include "sub_nums.h"
#include "mul_nums.h"
#include "div_nums.h"
#include "spc_nums.h"

double add_nums(double a, double b) {
    return a + b;
}

double sub_nums(double a, double b) {
    return b - a;
}

double mul_nums(double a, double b) {
    return a * b;
}

double div_nums(double a, double b) {
    if (a == 0) return 0; // Cannot divide by 0
    
    return b / a;
}

// Uses "poor man's pow" to determine the power of a fractional exponent.
double pow(double x, double exp) {
    if (x == 0) return 0;
    if (exp == 0) return 1;
    if (exp < 0) return 1 / pow(x, -exp);
    
    int full_part = (int) exp;
    double frac_part = exp - full_part;
    double result = 1.0;
    
    // int pow
    for (size_t i = 0; i < full_part; i++) {
        result *= x;
    }
    
    // Approximate fraction
    if (frac_part != 0) {
        double temp = 1.0;
        double term = 1.0;
        
        for (size_t i = 1; i < POOR_MANS_POW_GUESSES; i++) {
            term *= (frac_part * (x - 1)) / i;
            temp += term;
        }
        
        result *= temp;
    }
    
    return result;
}

// Uses Newton's Square Root to get a decent guess of the sqrt.
double sqrt(double x) {
    if (x <= 0) return 0; // Negative roots are way out of scope for this thesis.
    
    double guess = x / 2.0;
    
    for (size_t i = 0; i < NEWTONIAN_DIV_GUESSES; i++) {
        guess = (guess + x / guess) / 2.0;
    }
    
    return guess;
}