X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=rpikern;a=blobdiff_plain;f=src%2Flibc%2Fmath.c;fp=src%2Flibc%2Fmath.c;h=8da9a154296ec1ad332621eb2eaf6b5c37a36cb3;hp=0000000000000000000000000000000000000000;hb=32ccc707bc0821d7ff4248fe9f58e92e9c6ebef9;hpb=203b43a75a028e9238307bd6e73768eb8e942071 diff --git a/src/libc/math.c b/src/libc/math.c new file mode 100644 index 0000000..8da9a15 --- /dev/null +++ b/src/libc/math.c @@ -0,0 +1,38 @@ +#include "math.h" + +static double calc_pow(double x, double y, double precision); + +double pow(double x, double y) +{ + if(y == 0.0 || y == -0.0) { + return 1.0; + } + if(y == 1.0) { + return x; + } + if(y == -INFINITY) { + return fabs(x) < 1.0 ? INFINITY : 0.0; + } + if(y == INFINITY) { + return fabs(x) < 1.0 ? 0.0 : INFINITY; + } + return calc_pow(x, y, 1e-6); +} + +static double calc_pow(double x, double y, double precision) +{ + if(y < 0.0) { + return 1.0 / calc_pow(x, -y, precision); + } + if(y >= 10.0) { + double p = calc_pow(x, y / 2.0, precision / 2.0); + return p * p; + } + if(y >= 1.0) { + return x * calc_pow(x, y - 1.0, precision); + } + if(precision >= 1) { + return __builtin_sqrt(x); + } + return __builtin_sqrt(calc_pow(x, y * 2.0, precision * 2.0)); +}