>From 5c343ae0e317459b5185eea3a7d4c24191a2c351 Mon Sep 17 00:00:00 2001 From: Mark H Weaver Date: Wed, 26 Jan 2011 09:43:04 -0500 Subject: [PATCH] Infinities are no longer rational * libguile/numbers.c (scm_rational_p): return #f for infinities, per R6RS. Previously it returned #t for real infinities. The real infinities and NaNs are still considered real by scm_real `real?' however, per R6RS. * test-suite/tests/numbers.test: Add test cases for `rational?' and `real?' applied to infinities and NaNs. * doc/ref/api-data.texi (Real and Rational Numbers): Update docs to reflect that infinities are irrational, and that `real?' is no longer implies `rational?'. * NEWS: Add NEWS entry, and combine with earlier entry about infinities no longer being integers. --- NEWS | 12 +++++++----- doc/ref/api-data.texi | 7 +++---- libguile/numbers.c | 18 +++++++++++++----- test-suite/tests/numbers.test | 12 +++++++++++- 4 files changed, 34 insertions(+), 15 deletions(-) diff --git a/NEWS b/NEWS index 80a8c32..5c6e968 100644 --- a/NEWS +++ b/NEWS @@ -25,11 +25,6 @@ scm_eqv_p `eqv?', scm_equal_p `equal?' and scm_real_equalp now return #t if both were real NaNs, or both were non-real complex NaNs. Use scm_nan_p `nan?' to test for NaNs. -*** Infinities are no longer integers. - -Following the R6RS, infinities (+inf.0 and -inf.0) are no longer -considered to be integers. - *** `expt' and `integer-expt' changes when the base is 0 While `(expt 0 0)' is still 1, and `(expt 0 N)' for N > 0 is still @@ -38,6 +33,13 @@ integer-expt. This is more correct, and conforming to R6RS, but seems to be incompatible with R5RS, which would return 0 for all non-zero values of N. +*** Infinities are no longer integers, nor rationals + +scm_integer_p `integer?' and scm_rational_p `rational?' now return +#f for infinities, per R6RS. Previously they returned #t for real +infinities. The real infinities and NaNs are still considered real +by scm_real `real?' however, per R6RS. + *** `inf?' and `nan?' now throw exceptions for non-numbers scm_inf_p `inf?' and scm_nan_p `nan?' now throw exceptions if passed diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 2055eb1..5df7ee4 100755 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -536,8 +536,7 @@ divisor (some platforms support signed zeroes @samp{0.0} and The real infinities are written @samp{+inf.0} and @samp{-inf.0}, respectively. This syntax is also recognized by @code{read} as an extension to the usual Scheme syntax. The infinities are considered to -be inexact, non-integer values. You can test for them using address@hidden +be inexact, irrational values. You can test for them using @code{inf?}. Dividing zero by an inexact zero yields a NaN (`not a number') value, although they are actually considered numbers by Scheme. NaNs are @@ -570,8 +569,8 @@ Note that the set of integer values forms a subset of the set of rational numbers, i. e. the predicate will also be fulfilled if @var{x} is an integer number. -Since Guile can not represent irrational numbers, every number -satisfying @code{real?} also satisfies @code{rational?} in Guile. +The only irrational real numbers representable by Guile are address@hidden, @samp{-inf.0}, and @samp{+nan.0}. @end deffn @deffn {Scheme Procedure} rationalize x eps diff --git a/libguile/numbers.c b/libguile/numbers.c index 7983a28..228d994 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -3291,8 +3291,18 @@ SCM_DEFINE (scm_real_p, "real?", 1, 0, 0, "fulfilled if @var{x} is an integer number.") #define FUNC_NAME s_scm_real_p { - /* we can't represent irrational numbers. */ - return scm_rational_p (x); + if (SCM_I_INUMP (x)) + return SCM_BOOL_T; + else if (SCM_IMP (x)) + return SCM_BOOL_F; + else if (SCM_BIGP (x)) + return SCM_BOOL_T; + else if (SCM_FRACTIONP (x)) + return SCM_BOOL_T; + else if (SCM_REALP (x)) + return SCM_BOOL_T; + else + return SCM_BOOL_F; } #undef FUNC_NAME @@ -3312,9 +3322,7 @@ SCM_DEFINE (scm_rational_p, "rational?", 1, 0, 0, return SCM_BOOL_T; else if (SCM_FRACTIONP (x)) return SCM_BOOL_T; - else if (SCM_REALP (x)) - /* due to their limited precision, all floating point numbers are - rational as well. */ + else if (SCM_REALP (x) && SCM_I_CDBL_IS_FINITE (SCM_REAL_VALUE (x))) return SCM_BOOL_T; else return SCM_BOOL_F; diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test index 76a498f..a3a0e72 100644 --- a/test-suite/tests/numbers.test +++ b/test-suite/tests/numbers.test @@ -1494,6 +1494,11 @@ (pass-if (real? (+ 1 fixnum-max))) (pass-if (real? (- 1 fixnum-min))) (pass-if (real? 1.3)) + (pass-if (real? +inf.0)) + (pass-if (real? -inf.0)) + (pass-if (real? +nan.0)) + (pass-if (not (real? +inf.0-inf.0i))) + (pass-if (not (real? +nan.0+nan.0i))) (pass-if (not (real? 3+4i))) (pass-if (not (real? #\a))) (pass-if (not (real? "a"))) @@ -1504,7 +1509,7 @@ (pass-if (not (real? (current-input-port))))) ;;; -;;; rational? (same as real? right now) +;;; rational? ;;; (with-test-prefix "rational?" @@ -1515,6 +1520,11 @@ (pass-if (rational? (+ 1 fixnum-max))) (pass-if (rational? (- 1 fixnum-min))) (pass-if (rational? 1.3)) + (pass-if (not (rational? +inf.0))) + (pass-if (not (rational? -inf.0))) + (pass-if (not (rational? +nan.0))) + (pass-if (not (rational? +inf.0-inf.0i))) + (pass-if (not (rational? +nan.0+nan.0i))) (pass-if (not (rational? 3+4i))) (pass-if (not (rational? #\a))) (pass-if (not (rational? "a"))) -- 1.5.6.5