adjust / on complex inexact numbers

Add a special case for a real divided by a complex, and remove
(probably) misguided special cases for inexact zero real and imaginary
parts. These changes bring complex `/` further in line for Racket and
Racket CS.

Related to racket/typed-racket#868
This commit is contained in:
Matthew Flatt 2019-11-06 05:23:05 -07:00
parent d1c65f7067
commit 470e82a65d
2 changed files with 10 additions and 22 deletions

View File

@ -877,6 +877,9 @@
(test -0.0+0.0i / 1.0+0.0i -1.0e-9-1.0e+300i)
(test -0.0-0.0i / 0.0+1.0i -1.0e+300-1.0e-9i)
(test -0.0-0.0i / +1i -1.0e+300-1.0e-9i)
(test +nan.0+nan.0i / 0.0+0.0i)
(test 0.0-0.0i / 9.18e+55 4.0+1.79e+308i)
(test 0.0+nan.0i / 9.18e+55+0.0i 4.0+1.79e+308i)
(test 3 / 1 1/3)
(test -3 / 1 -1/3)

View File

@ -227,31 +227,16 @@ Scheme_Object *scheme_complex_divide(const Scheme_Object *_n, const Scheme_Objec
return scheme_make_complex(r, i);
}
if (b == zero) {
/* As in Chez Scheme: a / c+di => c(a/(cc+dd)) + (-d(a/cc+dd))i */
cm = scheme_bin_div(a, scheme_bin_plus(scheme_bin_mult(c, c), scheme_bin_mult(d, d)));
return scheme_make_complex(scheme_bin_mult(c, cm),
scheme_bin_minus(zero, scheme_bin_mult(d, cm)));
}
if (!SCHEME_FLOATP(a) && !SCHEME_FLOATP(b) && !SCHEME_FLOATP(c) && !SCHEME_FLOATP(d))
return simple_complex_divide(a, b, c, d, 0);
if (scheme_is_zero(d)) {
/* This is like dividing by a real number, except that
the inexact 0 imaginary part can interact with +inf.0 and +nan.0 */
r = scheme_bin_plus(scheme_bin_div(a, c),
/* Either 0.0 or +nan.0: */
scheme_bin_mult(d, b));
i = scheme_bin_minus(scheme_bin_div(b, c),
/* Either 0.0 or +nan.0: */
scheme_bin_mult(d, a));
return scheme_make_complex(r, i);
}
if (scheme_is_zero(c)) {
r = scheme_bin_plus(scheme_bin_div(b, d),
/* Either 0.0 or +nan.0: */
scheme_bin_mult(c, a));
i = scheme_bin_minus(scheme_bin_mult(c, b), /* either 0.0 or +nan.0 */
scheme_bin_div(a, d));
return scheme_make_complex(r, i);
}
aa[0] = c;
cm = scheme_abs(1, aa);
aa[0] = d;