Check for 0.0 imaginary part in exp.

Follows Chez Scheme and Guile. Turns `(exp 10000.+0.0i)` into
`+inf.0+0.0i` instead of `+inf.0+nan.0i`, which is analagous to
the behavior for exact 0 in the complex part.

Fixes #3194.
This commit is contained in:
Sam Tobin-Hochstadt 2020-05-20 15:30:32 -04:00 committed by Sam Tobin-Hochstadt
parent 2768499b88
commit ec0964861f
2 changed files with 15 additions and 0 deletions

View File

@ -2243,6 +2243,14 @@
(test 1.0 exp -0.0) (test 1.0 exp -0.0)
(test 272.0 round (* 100 (exp 1))) (test 272.0 round (* 100 (exp 1)))
;; should not be NaN
(test +inf.0+0.0i exp 10000000.0+0.0i)
(test +inf.0-0.0i exp 10000000.0-0.0i)
#reader "maybe-single.rkt"
(when has-single-flonum?
(test +inf.f+0.0f0i exp +100000.0f0+0.0f0i)
(test +inf.f-0.0f0i exp +100000.0f0-0.0f0i))
(test 0 log 1) (test 0 log 1)
(test 0.0 log 1.0) (test 0.0 log 1.0)
(test -inf.0 log 0.0) (test -inf.0 log 0.0)

View File

@ -2798,6 +2798,13 @@ static Scheme_Object *complex_exp(Scheme_Object *c)
Scheme_Object *cos_a, *sin_a; Scheme_Object *cos_a, *sin_a;
r = exp_prim(1, &r); r = exp_prim(1, &r);
/* If i is 0.0, avoid computing the cos/sin, since that can end up
producing NaN. */
if (SCHEME_FLOATP(i) && (SCHEME_FLOAT_VAL(i) == 0.0)) {
return scheme_make_complex(r, i);
}
cos_a = cos_prim(1, &i); cos_a = cos_prim(1, &i);
sin_a = sin_prim(1, &i); sin_a = sin_prim(1, &i);