fixed more binutils issues (newer gcc/libc)
[zpugcc/jano.git] / toolchain / gcc / newlib / libm / mathfp / sf_pow.c
blob932e75dbbbad13297a10a8d6e9011288e4b171e1
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 && y <= 0.0)
34 errno = EDOM;
36 else if ((t = y * log (fabsf (x))) >= BIGX)
38 errno = ERANGE;
39 if (px & 0x80000000)
41 /* x is negative. */
42 if (k)
44 /* y is not an integer. */
45 errno = EDOM;
46 x = 0.0;
48 else if (exponent_is_even_int)
49 x = z_infinity_f.f;
50 else
51 x = -z_infinity_f.f;
53 else
55 x = z_infinity_f.f;
58 else if (t < SMALLX)
60 errno = ERANGE;
61 x = 0.0;
63 else
65 if ( !k && fabsf (d) <= 32767 )
67 n = (int) d;
69 if ((sign = (n < 0)))
70 n = -n;
72 while ( n > 0 )
74 if ((unsigned int) n % 2)
75 r *= x;
76 x *= x;
77 n = (unsigned int) n / 2;
80 if (sign)
81 r = 1.0 / r;
83 return r;
85 else
87 if ( px & 0x80000000 )
89 /* x is negative. */
90 if (k)
92 /* y is not an integer. */
93 errno = EDOM;
94 return 0.0;
98 x = exp (t);
100 if (!exponent_is_even_int)
102 if (px & 0x80000000)
104 /* y is an odd integer, and x is negative,
105 so the result is negative. */
106 GET_FLOAT_WORD (px, x);
107 px |= 0x80000000;
108 SET_FLOAT_WORD (x, px);
114 return x;
117 #ifdef _DOUBLE_IS_32BITS
119 double pow (double x, double y)
121 return (double) powf ((float) x, (float) y);
124 #endif /* defined(_DOUBLE_IS_32BITS) */