From 470e82a65d04d7227d7bd65d1ea94d5dd9cae532 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 6 Nov 2019 05:23:05 -0700 Subject: [PATCH] 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 --- .../racket-test-core/tests/racket/number.rktl | 3 ++ racket/src/racket/src/complex.c | 29 +++++-------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index 8f73947679..d8846db324 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -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) diff --git a/racket/src/racket/src/complex.c b/racket/src/racket/src/complex.c index 76d8c7962b..045b105ce6 100644 --- a/racket/src/racket/src/complex.c +++ b/racket/src/racket/src/complex.c @@ -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;