diff options
author | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
---|---|---|
committer | Christopher Faylor <me@cgf.cx> | 2000-02-17 19:39:52 +0000 |
commit | 8a0efa53e44919bcf5ccb1d3353618a82afdf8bc (patch) | |
tree | 68c3dbf3f2c6fd5d49777def9914d77b5cd4589d /newlib/libm/mathfp/sf_pow.c | |
parent | 1fd5e000ace55b323124c7e556a7a864b972a5c4 (diff) | |
download | cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.gz cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.tar.bz2 cygnal-8a0efa53e44919bcf5ccb1d3353618a82afdf8bc.zip |
import newlib-2000-02-17 snapshot
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 000000000..2b3bed3c7 --- /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) */ |