diff options
| author | Jakob Kaivo <jkk@ung.org> | 2019-03-03 21:25:50 -0500 |
|---|---|---|
| committer | Jakob Kaivo <jkk@ung.org> | 2019-03-03 21:25:50 -0500 |
| commit | 06696f40afe58a231e2531c8bf6d9f0dadb92e51 (patch) | |
| tree | b146422c6326ffe3debf3163f0941d8dda0be105 /src/math/pow.c | |
| parent | f20eeea657d62f2ef905627ca3a9094d33af7d40 (diff) | |
outline details from C18 annex F
Diffstat (limited to 'src/math/pow.c')
| -rw-r--r-- | src/math/pow.c | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/math/pow.c b/src/math/pow.c index c0d613e5..8a070005 100644 --- a/src/math/pow.c +++ b/src/math/pow.c @@ -2,10 +2,91 @@ #include <math.h> #include "_tgmath.h" #include "errno.h" +#include "fenv.h" /** exponentiation **/ TYPE TGFN(pow)(TYPE x, TYPE y) { + int classx = fpclassify(x); + int classy = fpclassify(y); + + if (classx == FP_ZERO) { + if (classy == FP_INFINITE && signbit(y)) { + feraiseexcept(FE_DIVBYZERO); + return INFINITY; + } + + if (y < 0) { + feraiseexcept(FE_DIVBYZERO); + /* if (y == odd integer) { */ + return signbit(x) ? - INFINITY : INFINITY; + /* } else { */ + return INFINITY; + /* } */ + } + + if (y > 0) { + /* if (y == odd integer) { */ + return x; + /* } else { */ + return 0.0; + /* } */ + } + } + + if (x == -1.0 && classy == FP_INFINITE) { + return 1; + } + + if (x == 1.0) { + return 1.0; + } + + if (classy == FP_ZERO) { + return 1.0; + } + + if (x < 0 /* && y != integer */) { + feraiseexcept(FE_INVALID); + return NAN; + } + + if (classy == FP_INFINITE) { + int sb = signbit(y); + TYPE ab = TGFN(fabs)(x); + if ((sb && ab < 1.0) || (!sb && ab > 1.0)) { + return INFINITY; + } else { + return 0.0; + } + } + + if (classx == FP_INFINITE) { + if (!signbit(x)) { + if (y < 0) { + return 0.0; + } else if (y > 0) { + return INFINITY; + } + } + + if (y < 0) { + /* if (y == odd integer ) { */ + return -0.0; + /* } else { */ + return 0.0; + /* } */ + } + + if (y > 0) { + /* if (y == odd integer ) { */ + return - INFINITY; + /* } else { */ + return INFINITY; + /* } */ + } + } + if (x < 0 /* && !isintegral(y) */) { errno = EDOM; /* ARGUMENT(x) is negative and ARGUMENT(y) is not an integer */ return TGHUGE; |
