From 3ef32d915ba6d07e5191aa980ba0a936e1970462 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 31 Jan 2011 19:16:33 -0700 Subject: [PATCH] make inexacts `eqv?' only when precision is the same plus some other small fixes --- collects/scribblings/reference/numbers.scrbl | 39 +++++++++++--------- collects/tests/racket/number.rktl | 4 +- collects/tests/racket/numstrs.rktl | 8 ++-- src/racket/src/bool.c | 2 +- src/racket/src/number.c | 2 +- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/collects/scribblings/reference/numbers.scrbl b/collects/scribblings/reference/numbers.scrbl index afdc69030d..3910473fd0 100644 --- a/collects/scribblings/reference/numbers.scrbl +++ b/collects/scribblings/reference/numbers.scrbl @@ -18,9 +18,9 @@ All @deftech{numbers} are @deftech{complex numbers}. Some of them are @deftech{real numbers}, and all of the real numbers that can be represented are also @deftech{rational numbers}, except for -@as-index{@racket[+inf.0]} (positive @as-index{infinity}), -@as-index{@racket[-inf.0]} (negative infinity), and -@as-index{@racket[+nan.0]} (@as-index{not-a-number}). Among the +@as-index{@racket[+inf.0]} and @as-index{@racket[+inf.f]} (positive @as-index{infinity}), +@as-index{@racket[-inf.0]} an @as-index{@racket[-inf.f]} (negative infinity), and +@as-index{@racket[+nan.0]} and @as-index{@racket[+nan.f]} (@as-index{not-a-number}). Among the rational numbers, some are @deftech{integers}, because @racket[round] applied to the number produces the same number. @@ -54,21 +54,26 @@ numbers). In particular, adding, multiplying, subtracting, and dividing exact numbers always produces an exact result. Inexact numbers can be coerced to exact form, except for the inexact -numbers @racket[+inf.0], @racket[-inf.0], and @racket[+nan.0], which +numbers @racket[+inf.0] (double-precision), @racket[+inf.f] (single-precision), +@racket[-inf.0], @racket[-inf.f], @racket[+nan.0], and @racket[+nan.f] which have no exact form. @index["division by inexact zero"]{Dividing} a number by exact zero raises an exception; dividing a non-zero number -other than @racket[+nan.0] by an inexact zero returns @racket[+inf.0] -or @racket[-inf.0], depending on the sign of the dividend. The +other than @racket[+nan.0] or @racket[+nan.f] by an inexact zero returns @racket[+inf.0], +@racket[+inf.f], @racket[-inf.0] +or @racket[-inf.f], depending on the sign and precision of the dividend. The @racket[+nan.0] value is not @racket[=] to itself, but @racket[+nan.0] -is @racket[eqv?] to itself. Conversely, @racket[(= 0.0 -0.0)] is -@racket[#t], but @racket[(eqv? 0.0 -0.0)] is @racket[#f]. The datum -@racketvalfont{-nan.0} refers to the same constant as @racket[+nan.0]. +is @racket[eqv?] to itself, and @racket[+nan.f] is similarly @racket[eqv?] but +not @racket[=] to itself. Conversely, @racket[(= 0.0 -0.0)] is +@racket[#t], but @racket[(eqv? 0.0 -0.0)] is @racket[#f], and the +same for @racket[0.0f0] and @racket[-0.0f0]. The datum +@racketvalfont{-nan.0} refers to the same constant as @racket[+nan.0], +and @racketvalfont{-nan.f} is the same as @racket[+nan.f], Calculations with infinites produce results consistent with IEEE double-precision floating point where IEEE specifies the result; in cases where IEEE provides no specification (e.g., @racket[(angle +inf.0+inf.0i)]), the result corresponds to the limit approaching -infinity, or @racket[+nan.0] if no such limit exists. +infinity, or @racket[+nan.0] or @racket[+nan.f] if no such limit exists. A @deftech{fixnum} is an exact integer whose two's complement representation fit into 31 bits on a 32-bit platform or 63 bits on a @@ -79,9 +84,9 @@ Two fixnums that are @racket[=] are also the same according to @racket[eq?]. Otherwise, the result of @racket[eq?] applied to two numbers is undefined. -Two numbers are @racket[eqv?] when they are both inexact or both -exact, and when they are @racket[=] (except for @racket[+nan.0], -@racket[+0.0], and @racket[-0.0], as noted above). Two numbers are +Two numbers are @racket[eqv?] when they are both inexact with the same precision or both +exact, and when they are @racket[=] (except for @racket[+nan.0], @racket[+nan.f], +@racket[+0.0], @racket[+0.0f0], @racket[-0.0], and @racket[-0.0f0], as noted above). Two numbers are @racket[equal?] when they are @racket[eqv?]. @local-table-of-contents[] @@ -217,12 +222,12 @@ number, @racket[#f] otherwise.} @mz-examples[(exact->inexact 1) (exact->inexact 1.0)]} -@defproc[(real->single-flonum [z real?]) single-flonum?]{ Coerces @racket[z] - to a single-precision floating-point number. If @racket[z] is already +@defproc[(real->single-flonum [x real?]) single-flonum?]{ Coerces @racket[x] + to a single-precision floating-point number. If @racket[x] is already a single-precision floating-point number, it is returned.} -@defproc[(real->double-flonum [z real?]) flonum?]{ Coerces @racket[z] - to a double-precision floating-point number. If @racket[z] is already +@defproc[(real->double-flonum [x real?]) flonum?]{ Coerces @racket[x] + to a double-precision floating-point number. If @racket[x] is already a double-precision floating-point number, it is returned.} @; ---------------------------------------- diff --git a/collects/tests/racket/number.rktl b/collects/tests/racket/number.rktl index 4159d18488..9adc86467c 100644 --- a/collects/tests/racket/number.rktl +++ b/collects/tests/racket/number.rktl @@ -2750,8 +2750,8 @@ (< a -1e38)))) (map (lambda (n) - (test #t close? n (floating-point-bytes->real (real->floating-point-bytes n 4 #t) #t)) - (test #t close? n (floating-point-bytes->real (real->floating-point-bytes n 4 #f) #f)) + (test #t close? (real->single-flonum n) (floating-point-bytes->real (real->floating-point-bytes n 4 #t) #t)) + (test #t close? (real->single-flonum n) (floating-point-bytes->real (real->floating-point-bytes n 4 #f) #f)) (test n floating-point-bytes->real (real->floating-point-bytes n 8 #t) #t) (test n floating-point-bytes->real (real->floating-point-bytes n 8 #f) #f)) (append diff --git a/collects/tests/racket/numstrs.rktl b/collects/tests/racket/numstrs.rktl index 023eb7ac3b..e4490fe132 100644 --- a/collects/tests/racket/numstrs.rktl +++ b/collects/tests/racket/numstrs.rktl @@ -13,10 +13,10 @@ (1/20000 "#e1/2e-4") (10.0 "1e1") (10.0 "1E1") - (10.0 "1s1") - (10.0 "1S1") - (10.0 "1f1") - (10.0 "1F1") + (10.0f0 "1s1") + (10.0f0 "1S1") + (10.0f0 "1f1") + (10.0f0 "1F1") (10.0 "1l1") (10.0 "1L1") (10.0 "1d1") diff --git a/src/racket/src/bool.c b/src/racket/src/bool.c index 263c3ff233..a61215f930 100644 --- a/src/racket/src/bool.c +++ b/src/racket/src/bool.c @@ -231,7 +231,7 @@ int scheme_eqv (Scheme_Object *obj1, Scheme_Object *obj2) t2 = SCHEME_TYPE(obj2); if (NOT_SAME_TYPE(t1, t2)) { -#ifdef MZ_USE_SINGLE_FLOATS +#ifdef EQUATE_FLOATS_OF_DIFFERENT_PRECISIONS /* If one is a float and the other is a double, coerce to double */ if ((t1 == scheme_float_type) && (t2 == scheme_double_type)) return double_eqv(SCHEME_FLT_VAL(obj1), SCHEME_DBL_VAL(obj2)); diff --git a/src/racket/src/number.c b/src/racket/src/number.c index 6fcb9d6610..2f73cb6968 100644 --- a/src/racket/src/number.c +++ b/src/racket/src/number.c @@ -1848,7 +1848,7 @@ static Scheme_Object *TO_FLOAT(const Scheme_Object *n) #define TO_DOUBLE_VAL scheme_get_val_as_double -#ifdef USE_SINGLE_FLOATS_AS_DEFAULT +#ifdef USE_SINGLE_FLOATS double TO_DOUBLE_VAL(const Scheme_Object *n) {