| /* | |
| * ==================================================== | |
| * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | |
| * | |
| * Developed at SunPro, a Sun Microsystems, Inc. business. | |
| * Permission to use, copy, modify, and distribute this | |
| * software is freely granted, provided that this notice | |
| * is preserved. | |
| * ==================================================== | |
| */ | |
| #include <math.h> | |
| #include <inttypes.h> | |
| #include <errno.h> | |
| /* NAN builtins for gcc, as they are not part of math.h */ | |
| #ifndef NANF | |
| #define NANF __builtin_nanf ("") | |
| #endif | |
| #ifndef NANL | |
| #define NANL __builtin_nanl ("") | |
| #endif | |
| extern double bsd__ieee754_fmod(double, double); | |
| extern float bsd__ieee754_fmodf(float, float); | |
| extern double bsd__ieee754_pow(double, double); | |
| extern float bsd__ieee754_powf(float, float); | |
| extern double bsd__ieee754_remainder(double, double); | |
| extern float bsd__ieee754_remainderf(float, float); | |
| static inline double softmath_fact(double number) | |
| { | |
| if (number <= 0) | |
| return 1; | |
| return number * softmath_fact(number - 1); | |
| } | |
| static inline float softmath_expf(float x) | |
| { | |
| float result = 0.0; | |
| int n; | |
| for(n = 0; n < 64; n++) | |
| { | |
| result += (bsd__ieee754_powf(x, n) / softmath_fact(n)); | |
| if (isnan(result) || isinf(result)) | |
| break; | |
| } | |
| return result; | |
| } | |
| static inline double softmath_log(double x) | |
| { | |
| int n, aprox = 8 / (x / 2); | |
| double result = 0.0; | |
| if (x == 0.0) | |
| return -HUGE_VALF; | |
| else if (x < 0.0001) | |
| aprox = 32768; | |
| if (aprox < 30) | |
| aprox = 30; | |
| for(n = 0; n < aprox; n++) | |
| { | |
| result += bsd__ieee754_pow((x - 1.0) / (x + 1.0), 2 * n + 1) * (1.0 / (2.0 * n + 1.0)); | |
| if (isinf(result)) | |
| break; | |
| } | |
| result *= 2; | |
| return result; | |
| } | |
| static inline float softmath_logf(float x) | |
| { | |
| int n, aprox = 8 / (x / 2); | |
| float result = 0.0; | |
| if (x == 0.0) | |
| return -HUGE_VALF; | |
| else if (x < 0.0001) | |
| aprox = 32768; | |
| if (aprox < 30) | |
| aprox = 30; | |
| for(n = 0; n < aprox; n++) | |
| { | |
| result += bsd__ieee754_powf((x - 1.0) / (x + 1.0), 2 * n + 1) * (1.0 / (2.0 * n + 1.0)); | |
| if (isinf(result)) | |
| break; | |
| } | |
| result *= 2; | |
| return result; | |
| } |