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

#ifndef DBL_EPSILON
#define DBL_EPSILON 2.2204460492503131e-16
#endif

float power(float a, float b)
{
    float res = 1;
    
    for (int i = 0; i < b; ++i)
    {
        res *= a;
    }
    
    return res;
}

double root(int n, double x)
{
    double d, r = 1;
    if (!x)
    {
        return 0;
    }
    
    if (n < 1 || (x < 0 && !(n&1)))
    {
        return 0.0 / 0.0;
    }
    
    do
    {
        d = (x / power(r, n - 1) - r) / n;
        r += d;
    } while (d >= DBL_EPSILON * 10 || d <= -DBL_EPSILON * 10);
    
    return r;
}


long gcd(long a, long b)
{
    return b == 0 ? a : gcd(b, a % b);
}

void frac(float value, long* numerator, long* denominator)
{
    double integral = floor(value);
    double frac = value - integral;
    const long precision = 1000000;
    
    long commonDenominator = gcd(round(frac * precision), precision);
    *numerator = round(frac * precision) / commonDenominator;
    *denominator = precision / commonDenominator;
    
    *numerator = *numerator + (integral * *denominator);
}

int main() {
    
    float base = 2;
    float exp = 2.5;
    
    
    printf("FIRST: %f\n", pow(base, exp));
    
    //OR
    
    //A ^ (B/C) is the same as CthRoot(A ^ B)
    long num = 0;
    long den = 0;
    frac(exp, &num, &den);
    
    printf("SECOND: %f\n", root(den, power(base, num)));
    
    
    base = 3;
    exp = 2.7;
    
    printf("THIRD: %f\n", pow(base, exp));
    
    //OR:
    
    num = 0;
    den = 0;
    frac(exp, &num, &den);
    
    printf("FOURTH: %f\n", root(den, power(base, num)));
    
    return 0;
}