diff options
author | Jakob Kaivo <jkk@ung.org> | 2019-03-03 21:19:47 -0500 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2019-03-03 21:19:47 -0500 |
commit | 8c7cdf31bd692e1697a5a01664717c3b9dbffc59 (patch) | |
tree | 948e7a2d189f5aba85e0f8be3386424290fdb231 /src/complex/cexp.c | |
parent | 6eb245579dfdefa0da7f59909bf2e3f8b277c426 (diff) |
fill out special cases outlined in C18 annex G
Diffstat (limited to 'src/complex/cexp.c')
-rw-r--r-- | src/complex/cexp.c | 68 |
1 files changed, 67 insertions, 1 deletions
diff --git a/src/complex/cexp.c b/src/complex/cexp.c index d343a02e..c6d7b537 100644 --- a/src/complex/cexp.c +++ b/src/complex/cexp.c @@ -1,10 +1,76 @@ # define TGSOURCE "../complex/cexp.c" #include "_tgmath.h" - #include <complex.h> +#include "math.h" +#include "fenv.h" TYPE complex TGFN(cexp)(TYPE complex z) { + int classr = fpclassify(TGFN(creal)(z)); + int classi = fpclassify(TGFN(cimag)(z)); + int signr = signbit(TGFN(creal)(z)); + //int signi = signbit(TGFN(cimag)(z)); + + if (classr == FP_ZERO && classi == FP_ZERO) { + return TGCMPLX(1.0, 0.0); + } + + if (classr != FP_INFINITE && classi == FP_INFINITE) { + feraiseexcept(FE_INVALID); + return TGCMPLX(NAN, NAN); + } + + if (classr != FP_INFINITE && classi == FP_NAN) { + feraiseexcept(FE_INVALID); + return TGCMPLX(NAN, NAN); + } + + if (classr == FP_INFINITE && classi == FP_ZERO) { + return TGCMPLX(INFINITY, 0.0); + } + + if (classr == FP_INFINITE && signr && classi != FP_INFINITE) { + TYPE y = TGFN(cimag)(z); + /* FIXME */ + return TGCMPLX(0 * TGFN(cos)(y), TGFN(sin)(y)); + } + + if (classr == FP_INFINITE && !signr && classi != FP_INFINITE && classi != FP_ZERO) { + TYPE y = TGFN(cimag)(z); + /* FIXME */ + return TGCMPLX(INFINITY * TGFN(cos)(y), TGFN(sin)(y)); + } + + if (classr == FP_INFINITE && signr && classi == FP_INFINITE) { + return TGCMPLX(INFINITY, INFINITY); + } + + if (classr == FP_INFINITE && !signr && classi == FP_INFINITE) { + feraiseexcept(FE_INVALID); + return TGCMPLX(INFINITY, NAN); + } + + if (classr == FP_INFINITE && signr && classi == FP_NAN) { + return TGCMPLX(0.0, 0.0); + } + + if (classr == FP_INFINITE && !signr && classi == FP_NAN) { + return TGCMPLX(INFINITY, NAN); + } + + if (classr == FP_NAN && classi == FP_ZERO) { + return TGCMPLX(NAN, 0.0); + } + + if (classr == FP_NAN && classi != FP_ZERO) { + feraiseexcept(FE_INVALID); + return TGCMPLX(NAN, NAN); + } + + if (classr == FP_NAN && classi == FP_NAN) { + return TGCMPLX(NAN, NAN); + } + return z; } |