| /* | 
 | * ==================================================== | 
 | * 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; | 
 | } |