diff options
Diffstat (limited to 'src/math/atan2.c')
| -rw-r--r-- | src/math/atan2.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/math/atan2.c b/src/math/atan2.c index c4c56a63..3b88b617 100644 --- a/src/math/atan2.c +++ b/src/math/atan2.c @@ -4,11 +4,60 @@ #include "errno.h" #include "nonstd/assert.h" +#include "M_PI.c" +#include "M_PI_2.c" + /** arc tangent **/ TYPE TGFN(atan2)(TYPE y, TYPE x) { + int classy = fpclassify(y); + int classx = fpclassify(x); ASSERT_NONZERO(x); + if (classy == FP_ZERO && classx == 0) { + if (signbit(x)) { + return copysign(M_PI, y); + } else { + return y; + } + } + + if (classy == FP_ZERO) { + if (x < 0) { + return copysign(M_PI, y); + } else if (x > 0) { + return y; + } + } + + if (classx == FP_ZERO) { + if (y < 0) { + return - M_PI_2; + } else if (y > 0) { + return M_PI_2; + } + } + + if (classx == FP_INFINITE) { + if (classy == FP_INFINITE) { + if (signbit(x)) { + return copysign(3.0 * M_PI / 4.0, y); + } else { + return copysign(M_PI / 4.0, y); + } + } else if (y > 0) { + if (signbit(x)) { + return copysign(M_PI, y); + } else { + return copysign(0.0, y); + } + } + } + + if (classy == FP_INFINITE && classx != FP_INFINITE) { + return copysign(M_PI_2, y); + } + if (y == 0 && x == 0) { errno = EDOM; /* ARGUMENT(y) and ARGUMENT(x) are both LITERAL(0)) */ return TGHUGE; |
