arithmetic: Return angle unit for atan2

Like for `arg`, `atan2` returns an angle.

Fixes: #1151

Signed-off-by: Christophe de Dinechin <christophe@dinechin.org>
This commit is contained in:
Christophe de Dinechin 2024-09-01 14:37:58 +02:00
parent 3bb852224b
commit 5e4b661bdd
3 changed files with 27 additions and 19 deletions

View file

@ -1179,6 +1179,15 @@ algebraic_p arithmetic::evaluate(id op,
id xt = x->type();
id yt = y->type();
if (op == ID_atan2 && Settings.SetAngleUnits() &&
is_real(xt) && is_real(yt))
{
settings::SaveSetAngleUnits save(false);
x = evaluate(op, xr, yr, ops);
add_angle(x);
return x;
}
// All non-numeric cases, e.g. string concatenation
// Must come first, e.g. for optimization of X^3 or list + tagged object
while(true)

View file

@ -505,10 +505,9 @@ algebraic_g rectangular::pifrac() const
if (!r || !i)
return nullptr;
angle_unit mode = Settings.AngleMode();
Settings.AngleMode(object::ID_PiRadians); // Enable 'exact' optimizations
settings::SaveAngleMode sam(ID_PiRadians); // Enable 'exact' optimizations
settings::SaveSetAngleUnits ssau(false); // Do not add angle to result
algebraic_g a = atan2::evaluate(i, r);
Settings.AngleMode(mode);
return a;
}

View file

@ -3181,16 +3181,16 @@ void tests::decimal_numerical_functions()
step("atan2 pos / pos quadrant")
.test(CLEAR, "3.21 1.23 atan2", ENTER)
.expect("1.20487562515280923400866910549530674");
.expect("1.20487562515280923400866910549530674r");
step("atan2 pos / neg quadrant")
.test(CLEAR, "3.21 -1.23 atan2", ENTER)
.expect("1.93671702843698400445397427778419614");
.expect("1.93671702843698400445397427778419614r");
step("atan2 neg / pos quadrant")
.test(CLEAR, "-3.21 1.23 atan2", ENTER)
.expect("-1.20487562515280923400866910549530674");
.expect("-1.20487562515280923400866910549530674r");
step("atan2 neg / neg quadrant")
.test(CLEAR, "-3.21 -1.23 atan2", ENTER)
.expect("-1.93671702843698400445397427778419614");
.expect("-1.93671702843698400445397427778419614r");
step("Restore default 24-digit precision");
test(CLEAR, "24 PRECISION 12 SIG", ENTER).noerror();
@ -3354,16 +3354,16 @@ void tests::float_numerical_functions()
step("atan2 pos / pos quadrant")
.test(CLEAR, "3.21 1.23 atan2", ENTER)
.expect("1.20488");
.expect("1.20488r");
step("atan2 pos / neg quadrant")
.test(CLEAR, "3.21 -1.23 atan2", ENTER)
.expect("1.93672");
.expect("1.93672r");
step("atan2 neg / pos quadrant")
.test(CLEAR, "-3.21 1.23 atan2", ENTER)
.expect("-1.20488");
.expect("-1.20488r");
step("atan2 neg / neg quadrant")
.test(CLEAR, "-3.21 -1.23 atan2", ENTER)
.expect("-1.93672");
.expect("-1.93672r");
step("Restore default 24-digit precision");
test(CLEAR, "24 PRECISION 12 SIG SoftFP", ENTER).noerror();
@ -3521,16 +3521,16 @@ void tests::double_numerical_functions()
step("atan2 pos / pos quadrant")
.test(CLEAR, "3.21 1.23 atan2", ENTER)
.expect("1.20487562515281");
.expect("1.20487562515281r");
step("atan2 pos / neg quadrant")
.test(CLEAR, "3.21 -1.23 atan2", ENTER)
.expect("1.93671702843698");
.expect("1.93671702843698r");
step("atan2 neg / pos quadrant")
.test(CLEAR, "-3.21 1.23 atan2", ENTER)
.expect("-1.20487562515281");
.expect("-1.20487562515281r");
step("atan2 neg / neg quadrant")
.test(CLEAR, "-3.21 -1.23 atan2", ENTER)
.expect("-1.93671702843698");
.expect("-1.93671702843698r");
step("Restore default 24-digit precision");
test(CLEAR, "24 PRECISION 12 SIG SoftFP", ENTER).noerror();
@ -3685,16 +3685,16 @@ void tests::high_precision_numerical_functions()
step("atan2 pos / pos quadrant")
.test(CLEAR, "3.21 1.23 atan2", ENTER)
.expect("1.2048756251528092340086691054953067432743544266849701001787193708647165615080559253255023322891723139676139226703142769");
.expect("1.2048756251528092340086691054953067432743544266849701001787193708647165615080559253255023322891723139676139226703142769r");
step("atan2 pos / neg quadrant")
.test(CLEAR, "3.21 -1.23 atan2", ENTER)
.expect("1.9367170284369840044539742777841961409228149726901357207962252214430998447781530733025324930529447540145341638429680297");
.expect("1.9367170284369840044539742777841961409228149726901357207962252214430998447781530733025324930529447540145341638429680297r");
step("atan2 neg / pos quadrant")
.test(CLEAR, "-3.21 1.23 atan2", ENTER)
.expect("-1.2048756251528092340086691054953067432743544266849701001787193708647165615080559253255023322891723139676139226703142769");
.expect("-1.2048756251528092340086691054953067432743544266849701001787193708647165615080559253255023322891723139676139226703142769r");
step("atan2 neg / neg quadrant")
.test(CLEAR, "-3.21 -1.23 atan2", ENTER)
.expect("-1.9367170284369840044539742777841961409228149726901357207962252214430998447781530733025324930529447540145341638429680297");
.expect("-1.9367170284369840044539742777841961409228149726901357207962252214430998447781530733025324930529447540145341638429680297r");
step("Restore default 24-digit precision");
test(CLEAR, "24 PRECISION 12 SIG", ENTER).noerror();