Cygwin: mmap: allow remapping part of an existing anonymous mapping
[newlib-cygwin.git] / newlib / libm / mathfp / sf_pow.c
blob489a71dd0b9dc3d0a23feb1ec1949602cf78fd38
2 /* @(#)z_powf.c 1.0 98/08/13 */
3 #include <float.h>
4 #include "fdlibm.h"
5 #include "zmath.h"
7 float powf (float x, float y)
9 float d, k, t, r = 1.0;
10 int n, sign, exponent_is_even_int = 0;
11 __int32_t px;
13 GET_FLOAT_WORD (px, x);
15 k = modff (y, &d);
17 if (k == 0.0)
19 /* Exponent y is an integer. */
20 if (modff (ldexpf (y, -1), &t))
22 /* y is odd. */
23 exponent_is_even_int = 0;
25 else
27 /* y is even. */
28 exponent_is_even_int = 1;
32 if (x == 0.0)
34 if (y <= 0.0)
35 errno = EDOM;
37 else if ((t = y * log (fabsf (x))) >= BIGX)
39 errno = ERANGE;
40 if (px & 0x80000000)
42 /* x is negative. */
43 if (k)
45 /* y is not an integer. */
46 errno = EDOM;
47 x = 0.0;
49 else if (exponent_is_even_int)
50 x = z_infinity_f.f;
51 else
52 x = -z_infinity_f.f;
54 else
56 x = z_infinity_f.f;
59 else if (t < SMALLX)
61 errno = ERANGE;
62 x = 0.0;
64 else
66 if ( !k && fabsf (d) <= 32767 )
68 n = (int) d;
70 if ((sign = (n < 0)))
71 n = -n;
73 while ( n > 0 )
75 if ((unsigned int) n % 2)
76 r *= x;
77 x *= x;
78 n = (unsigned int) n / 2;
81 if (sign)
82 r = 1.0 / r;
84 return r;
86 else
88 if ( px & 0x80000000 )
90 /* x is negative. */
91 if (k)
93 /* y is not an integer. */
94 errno = EDOM;
95 return 0.0;
99 x = exp (t);
101 if (!exponent_is_even_int)
103 if (px & 0x80000000)
105 /* y is an odd integer, and x is negative,
106 so the result is negative. */
107 GET_FLOAT_WORD (px, x);
108 px |= 0x80000000;
109 SET_FLOAT_WORD (x, px);
115 return x;
118 #ifdef _DOUBLE_IS_32BITS
120 double pow (double x, double y)
122 return (double) powf ((float) x, (float) y);
125 #endif /* defined(_DOUBLE_IS_32BITS) */