hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit e089ea45150cedd9e8edc4b2c22e55580e98a25e
parent 46190589404158b83117581c002ced9751ef4a55
Author: Sebastian <sebastian@sebsite.pw>
Date:   Fri, 27 May 2022 22:28:35 -0400

math: add atan2f64

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mmath/data+test.ha | 12++++++++++++
Mmath/trig.ha | 53+++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/math/data+test.ha b/math/data+test.ha @@ -115,6 +115,18 @@ const TEST_ATAN: [_]f64 = [ 1.0696031952318783760193244e+00, -1.4561721938838084990898679e+00, ]; +const TEST_ATAN2: [_]f64 = [ + 1.1088291730037004444527075e+00, + 9.1218183188715804018797795e-01, + 1.5984772603216203736068915e+00, + 2.0352918654092086637227327e+00, + 8.0391819139044720267356014e-01, + 1.2861075249894661588866752e+00, + 1.0889904479131695712182587e+00, + 1.3044821793397925293797357e+00, + 1.3902530903455392306872261e+00, + 2.2859857424479142655411058e+00, +]; const TEST_ATANH: [_]f64 = [ 5.4651163712251938116878204e-01, 1.0299474112843111224914709e+00, diff --git a/math/trig.ha b/math/trig.ha @@ -1013,6 +1013,59 @@ export fn atanhf64(x: f64) f64 = { assert(isnan(atanhf64(NAN))); }; +// Returns the arctangent, in radians, of y / x. +export fn atan2f64(y: f64, x: f64) f64 = { + if (isnan(y) || isnan(x)) { + return NAN; + } else if (y == 0f64) { + x = if (x >= 0f64 && signf64(x) > 0) 0f64 else PI; + return copysignf64(x, y); + } else if (x == 0f64) { + return copysignf64(PI / 2f64, y); + } else if (isinf(x)) { + if (signf64(x) > 0) { + x = if (isinf(y)) PI / 4f64 else 0f64; + return copysignf64(x, y); + } else { + x = if (isinf(y)) 3f64 * PI / 4f64 else PI; + return copysignf64(x, y); + }; + } else if (isinf(y)) { + return copysignf64(PI / 2f64, y); + }; + + const q = atanf64(y / x); + if (x < 0f64) { + return if (q <= 0f64) q + PI else q - PI; + }; + return q; +}; + +@test fn atan2() void = { + for (let idx = 0z; idx < 10; idx += 1) { + assert(isclose( + atan2f64(10f64, TEST_INPUTS[idx]), + TEST_ATAN2[idx])); + }; + assert(isnan(atan2f64(-INF, NAN))); + assert(atan2f64(-PI, INF) == -0f64); + assert(isnan(atan2f64(-PI, NAN))); + assert(atan2f64(-0f64, 0f64) == -0f64); + assert(atan2f64(-0f64, PI) == -0f64); + assert(atan2f64(-0f64, INF) == -0f64); + assert(isnan(atan2f64(-0f64, NAN))); + assert(atan2f64(0f64, 0f64) == 0f64); + assert(atan2f64(0f64, PI) == 0f64); + assert(atan2f64(0f64, INF) == 0f64); + assert(isnan(atan2f64(0f64, NAN))); + assert(atan2f64(PI, INF) == 0f64); + assert(atan2f64(1f64, INF) == 0f64); + assert(atan2f64(-1f64, INF) == -0f64); + assert(isnan(atan2f64(PI, NAN))); + assert(isnan(atan2f64(INF, NAN))); + assert(isnan(atan2f64(NAN, NAN))); +}; + // Returns the square root of a*a + b*b, taking care to avoid unnecessary // overflow and underflow. export fn hypotf64(a: f64, b: f64) f64 = {