diff options
author | PikalaxALT <pikalaxalt@gmail.com> | 2017-12-15 09:38:53 -0500 |
---|---|---|
committer | PikalaxALT <pikalaxalt@gmail.com> | 2017-12-15 09:39:34 -0500 |
commit | f95a4a932476be2ba99e2fd081e8d2bc6ea12813 (patch) | |
tree | 75f67192cb2d7b7b575c94edda318e475239b63c /newlib/libm/mathfp/sf_pow.c | |
parent | f60aca96985e68c7d8a52eb7bc955fb80e132f73 (diff) |
Import newlib and create makefile
Diffstat (limited to 'newlib/libm/mathfp/sf_pow.c')
-rw-r--r-- | newlib/libm/mathfp/sf_pow.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/newlib/libm/mathfp/sf_pow.c b/newlib/libm/mathfp/sf_pow.c new file mode 100644 index 0000000..2b3bed3 --- /dev/null +++ b/newlib/libm/mathfp/sf_pow.c @@ -0,0 +1,107 @@ + +/* @(#)z_powf.c 1.0 98/08/13 */ +#include <float.h> +#include "fdlibm.h" +#include "zmath.h" + +float powf (float x, float y) +{ + float d, t, r = 1.0; + int n, k, sign = 0; + __int32_t px; + + GET_FLOAT_WORD (px, x); + + k = modff (y, &d); + if (k == 0.0) + { + if (modff (ldexpf (y, -1), &t)) + sign = 0; + else + sign = 1; + } + + if (x == 0.0 && y <= 0.0) + errno = EDOM; + + else if ((t = y * log (fabsf (x))) >= BIGX) + { + errno = ERANGE; + if (px & 0x80000000) + { + if (!k) + { + errno = EDOM; + x = 0.0; + } + else if (sign) + x = -z_infinity_f.f; + else + x = z_infinity_f.f; + } + + else + x = z_infinity_f.f; + } + + else if (t < SMALLX) + { + errno = ERANGE; + x = 0.0; + } + + else + { + if ( k && fabsf (d) <= 32767 ) + { + n = (int) d; + + if (sign = (n < 0)) + n = -n; + + while ( n > 0 ) + { + if ((unsigned int) n % 2) + r *= x; + x *= x; + n = (unsigned int) n / 2; + } + + if (sign) + r = 1.0 / r; + + return r; + } + + else + { + if ( px & 0x80000000 ) + { + if ( !k ) + { + errno = EDOM; + return 0.0; + } + } + + x = exp (t); + + if ( sign ) + { + px ^= 0x80000000; + SET_FLOAT_WORD (x, px); + } + } + } + + return x; +} + +#ifdef _DOUBLE_IS_32BITS + +double pow (double x, double y) +{ + return (double) powf ((float) x, (float) y); +} + +#endif /* defined(_DOUBLE_IS_32BITS) */ |