From 8a0efa53e44919bcf5ccb1d3353618a82afdf8bc Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Thu, 17 Feb 2000 19:39:52 +0000 Subject: import newlib-2000-02-17 snapshot --- newlib/libm/mathfp/s_pow.c | 146 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 newlib/libm/mathfp/s_pow.c (limited to 'newlib/libm/mathfp/s_pow.c') diff --git a/newlib/libm/mathfp/s_pow.c b/newlib/libm/mathfp/s_pow.c new file mode 100644 index 000000000..7c0a38a20 --- /dev/null +++ b/newlib/libm/mathfp/s_pow.c @@ -0,0 +1,146 @@ + +/* @(#)z_pow.c 1.0 98/08/13 */ + +/* +FUNCTION + <>, <>---x to the power y +INDEX + pow +INDEX + powf + + +ANSI_SYNOPSIS + #include + double pow(double <[x]>, double <[y]>); + float pow(float <[x]>, float <[y]>); + +TRAD_SYNOPSIS + #include + double pow(<[x]>, <[y]>); + double <[x]>, <[y]>; + + float pow(<[x]>, <[y]>); + float <[x]>, <[y]>; + +DESCRIPTION + <> and <> calculate <[x]> raised to the exp1.0nt <[y]>. + @tex + (That is, $x^y$.) + @end tex + +RETURNS + On success, <> and <> return the value calculated. + + When the argument values would produce overflow, <> + returns <> and set <> to <>. If the + argument <[x]> passed to <> or <> is a negative + noninteger, and <[y]> is also not an integer, then <> + is set to <>. If <[x]> and <[y]> are both 0, then + <> and <> return <<1>>. + + You can modify error handling for these functions using <>. + +PORTABILITY + <> is ANSI C. <> is an extension. */ + +#include +#include "fdlibm.h" +#include "zmath.h" + +#ifndef _DOUBLE_IS_32BITS + +double pow (double x, double y) +{ + double d, t, r = 1.0; + int n, k, sign = 0; + __uint32_t px; + + GET_HIGH_WORD (px, x); + + k = modf (y, &d); + if (k == 0.0) + { + if (modf (ldexp (y, -1), &t)) + sign = 0; + else + sign = 1; + } + + if (x == 0.0 && y <= 0.0) + errno = EDOM; + + else if ((t = y * log (fabs (x))) >= BIGX) + { + errno = ERANGE; + if (px & 0x80000000) + { + if (!k) + { + errno = EDOM; + x = 0.0; + } + else if (sign) + x = -z_infinity.d; + else + x = z_infinity.d; + } + + else + x = z_infinity.d; + } + + else if (t < SMALLX) + { + errno = ERANGE; + x = 0.0; + } + + else + { + if ( k && fabs(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_HIGH_WORD (x, px); + } + } + } + + return x; +} + +#endif _DOUBLE_IS_32BITS -- cgit v1.2.3