summaryrefslogtreecommitdiff
path: root/newlib/libm/mathfp/sf_pow.c
diff options
context:
space:
mode:
authorPikalaxALT <pikalaxalt@gmail.com>2017-12-15 09:38:53 -0500
committerPikalaxALT <pikalaxalt@gmail.com>2017-12-15 09:39:34 -0500
commitf95a4a932476be2ba99e2fd081e8d2bc6ea12813 (patch)
tree75f67192cb2d7b7b575c94edda318e475239b63c /newlib/libm/mathfp/sf_pow.c
parentf60aca96985e68c7d8a52eb7bc955fb80e132f73 (diff)
Import newlib and create makefile
Diffstat (limited to 'newlib/libm/mathfp/sf_pow.c')
-rw-r--r--newlib/libm/mathfp/sf_pow.c107
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) */