diff --git a/collects/scribblings/reference/reader.scrbl b/collects/scribblings/reference/reader.scrbl index 39d9fe86f1..dbdf6a4d37 100644 --- a/collects/scribblings/reference/reader.scrbl +++ b/collects/scribblings/reference/reader.scrbl @@ -230,6 +230,10 @@ an exponent and specify a numerical precision. If single-precision IEEE floating point is supported (see @secref["numbers"]), the marks @litchar{f} and @litchar{s} specifies single-precision. Otherwise, or with any other mark, double-precision IEEE floating point is used. +In addition, single- and double-precision specials are distinct; +specials with the @litchar{.0} suffix, like @racket[-nan.0] are +double-precision, wheras specials with the @litchar{.f} suffix are +single-precision. @BNF[(list @nunterm{number} @BNF-alt[@nunterm{exact} @nunterm{inexact}]) @@ -251,7 +255,7 @@ with any other mark, double-precision IEEE floating point is used. (list @nunterm{inexact-simple} @BNF-seq[@nunterm{digits#} @optional{@litchar{.}} @kleenestar{@litchar{#}}] @BNF-seq[@optional{@nunterm{exact-integer}} @litchar{.} @nunterm{digits#}] @BNF-seq[@nunterm{digits#} @litchar{/} @nunterm{digits#}]) - (list @nunterm{inexact-special} @BNF-alt[@litchar{inf.0} @litchar{nan.0}]) + (list @nunterm{inexact-special} @BNF-alt[@litchar{inf.0} @litchar{nan.0} @litchar{inf.f} @litchar{nan.f}]) (list @nunterm{digits#} @BNF-seq[@kleeneplus{@nunterm{digit}} @kleenestar{@litchar{#}}]) (list @nunterm{inexact-complex} @BNF-seq[@optional{@nunterm{inexact-real}} @nonterm{sign} @nunterm{inexact-unsigned} @litchar{i}] @BNF-seq[@nunterm{inexact-real} @litchar["@"] @nunterm{inexact-real}]) diff --git a/collects/tests/racket/number.rktl b/collects/tests/racket/number.rktl index 6ea1461516..8117dacfe4 100644 --- a/collects/tests/racket/number.rktl +++ b/collects/tests/racket/number.rktl @@ -99,6 +99,30 @@ (test #f rational? +nan.0) (test #f integer? +nan.0) +(test #t number? +inf.f) +(test #t complex? +inf.f) +(test #t real? +inf.f) +(test #f rational? +inf.f) +(test #f integer? +inf.f) + +(test #t number? -inf.f) +(test #t complex? -inf.f) +(test #t real? -inf.f) +(test #f rational? -inf.f) +(test #f integer? -inf.f) + +(test #t number? +nan.f) +(test #t complex? +nan.f) +(test #t real? +nan.f) +(test #f rational? +nan.f) +(test #f integer? +nan.f) + +(test #t number? -nan.f) +(test #t complex? -nan.f) +(test #t real? -nan.f) +(test #f rational? -nan.f) +(test #f integer? -nan.f) + (arity-test inexact? 1 1) (arity-test number? 1 1) (arity-test complex? 1 1) diff --git a/collects/tests/racket/numstrs.rktl b/collects/tests/racket/numstrs.rktl index 9eead56d6b..023eb7ac3b 100644 --- a/collects/tests/racket/numstrs.rktl +++ b/collects/tests/racket/numstrs.rktl @@ -39,6 +39,10 @@ (-inf.0 "-1e10000000000000000000000000000000") (+inf.0 "1#e10000000000000000000000000000000") (-inf.0 "-1#e10000000000000000000000000000000") + (+inf.f "+inf.f") + (-inf.f "-inf.f") + (+nan.f "+nan.f") + (-nan.f "-nan.f") (+0.0 "1e-10000000000000000000000000000000") (-0.0 "-1e-10000000000000000000000000000000") (+0.0 "1#e-10000000000000000000000000000000") @@ -193,7 +197,11 @@ (-inf.0i "-inf.0i") (+nan.0i "+nan.0i") (-nan.0i "-nan.0i") + (+nan.fi "+nan.fi") + (-nan.fi "-nan.fi") (+inf.0i "+INF.0i") + (+inf.fi "+inf.fi") + (-inf.fi "-inf.fi") (-inf.0-nan.0i "-inf.0-nan.0i") (#f "1++inf.0i") (+nan.0@1 "+nan.0@1") diff --git a/src/racket/src/numstr.c b/src/racket/src/numstr.c index 3052794a52..a59203c217 100644 --- a/src/racket/src/numstr.c +++ b/src/racket/src/numstr.c @@ -60,6 +60,13 @@ READ_ONLY static char *infinity_str = "+inf.0"; READ_ONLY static char *minus_infinity_str = "-inf.0"; READ_ONLY static char *not_a_number_str = "+nan.0"; READ_ONLY static char *other_not_a_number_str = "-nan.0"; +/* Single-precision float literals. + Due to the structure of the reader, they have to be exactly 6 + characters long. */ +READ_ONLY static char *single_infinity_str = "+inf.f"; +READ_ONLY static char *single_minus_infinity_str = "-inf.f"; +READ_ONLY static char *single_not_a_number_str = "+nan.f"; +READ_ONLY static char *single_other_not_a_number_str = "-nan.f"; #if !defined(SIXTY_FOUR_BIT_INTEGERS) && defined(NO_LONG_LONG_TYPE) SHARED_OK static Scheme_Object *num_limits[3]; @@ -238,6 +245,30 @@ static Scheme_Object *read_special_number(const mzchar *str, int pos) return scheme_single_nan_object; #else return scheme_nan_object; +#endif + } + /* Single-precision specials + If single-precision float support is disabled, promote. */ + else if (!u_strcmp(s, single_infinity_str)) { +#ifdef MZ_USE_SINGLE_FLOATS + return scheme_single_inf_object; +#else + return scheme_inf_object; +#endif + } + else if (!u_strcmp(s, single_minus_infinity_str)) { +#ifdef MZ_USE_SINGLE_FLOATS + return scheme_single_minus_inf_object; +#else + return scheme_minus_inf_object; +#endif + } + else if (!u_strcmp(s, single_not_a_number_str) + || !u_strcmp(s, single_other_not_a_number_str)) { +#ifdef MZ_USE_SINGLE_FLOATS + return scheme_single_nan_object; +#else + return scheme_nan_object; #endif } }