From c93837c2ce5158e3a3e786feb8d8f6a3520a1f6c Mon Sep 17 00:00:00 2001 From: David Van Horn Date: Tue, 15 Dec 2020 21:24:28 -0500 Subject: [PATCH] Fix rationalize with +nan.0 tolerance Calling `rationalize` with `+nan.0` as the second argument was causing a "no exact representation error." This commit changes it to produce `+nan.0`. There was an unexercised set of tests for `rationalize` in the test suite which, once called, demonstrate the bug. Those tests also specify that `rationalize` should produce an exact result when the first argument is exact and the second is an infinity. That's not what the implementation does; it coerces the result to inexact. I changed the test cases to match the implementation, which is consistent with other Schemes (Chez, MIT) and standards (R6RS). --- pkgs/racket-test-core/tests/racket/number.rktl | 8 ++++---- racket/collects/racket/private/misc.rkt | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/number.rktl b/pkgs/racket-test-core/tests/racket/number.rktl index 3839e7180c..1d7367b803 100644 --- a/pkgs/racket-test-core/tests/racket/number.rktl +++ b/pkgs/racket-test-core/tests/racket/number.rktl @@ -2440,16 +2440,16 @@ (err/rt-test (rationalize .3+0.0i 1/10)) (define (test-rat-inf v) - (define zero (if (exact? v) 0 0.0)) - (test +inf.0 rationalize +inf.0 v) (test -inf.0 rationalize -inf.0 v) (test-nan.0 rationalize +nan.0 v) - (test zero rationalize v +inf.0) - (test zero rationalize v -inf.0) + (test 0.0 rationalize v +inf.0) + (test 0.0 rationalize v -inf.0) (test-nan.0 rationalize v +nan.0)) +(test-rat-inf 1/3) + (let loop ([i 100]) (unless (= i -100) (test (/ i 100) rationalize (inexact->exact (/ i 100.0)) 1/100000) diff --git a/racket/collects/racket/private/misc.rkt b/racket/collects/racket/private/misc.rkt index 4dda2f1c3c..f5c72b4676 100644 --- a/racket/collects/racket/private/misc.rkt +++ b/racket/collects/racket/private/misc.rkt @@ -68,12 +68,12 @@ [lo (- x delta)] [hi (+ x delta)]) (cond - [(equal? x +nan.0) x] + [(not (= x x)) x] [(or (equal? x +inf.0) (equal? x -inf.0)) (if (equal? delta +inf.0) +nan.0 x)] [(equal? delta +inf.0) 0.0] - [(not (= x x)) +nan.0] + [(not (= within within)) within] [(<= lo 0 hi) (if (exact? x) 0 0.0)] [(or (inexact? lo) (inexact? hi)) (exact->inexact (do-find-between (inexact->exact lo) (inexact->exact hi)))]