both returned #t. R5RS requires that `equal?' behave like
`eqv?' when comparing numbers.
-*** 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
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.
+
+*** NaNs are no longer rationals
+
+scm_rational_p `rational?' now returns #f for NaN values, per R6RS.
+Previously it returned #t for real NaN values. They are still
+considered real by scm_real `real?' however, per R6RS.
+
*** `inf?' and `nan?' now throw exceptions for non-reals
The domain of `inf?' and `nan?' is the real numbers. Guile now signals
@m{\pi,pi}.
Guile can represent both exact and inexact rational numbers, but it
-can not represent irrational numbers. Exact rationals are represented
-by storing the numerator and denominator as two exact integers.
-Inexact rationals are stored as floating point numbers using the C
-type @code{double}.
+cannot represent precise finite irrational numbers. Exact rationals are
+represented by storing the numerator and denominator as two exact
+integers. Inexact rationals are stored as floating point numbers using
+the C type @code{double}.
Exact rationals are written as a fraction of integers. There must be
no whitespace around the slash:
4.0
@end lisp
-The limited precision of Guile's encoding means that any ``real'' number
-in Guile can be written in a rational form, by multiplying and then dividing
-by sufficient powers of 10 (or in fact, 2). For example,
-@samp{-0.00000142857931198} is the same as @minus{}142857931198 divided by
-100000000000000000. In Guile's current incarnation, therefore, the
-@code{rational?} and @code{real?} predicates are equivalent.
-
-
-Dividing by an exact zero leads to a error message, as one might
-expect. However, dividing by an inexact zero does not produce an
-error. Instead, the result of the division is either plus or minus
-infinity, depending on the sign of the divided number.
+The limited precision of Guile's encoding means that any finite ``real''
+number in Guile can be written in a rational form, by multiplying and
+then dividing by sufficient powers of 10 (or in fact, 2). For example,
+@samp{-0.00000142857931198} is the same as @minus{}142857931198 divided
+by 100000000000000000. In Guile's current incarnation, therefore, the
+@code{rational?} and @code{real?} predicates are equivalent for finite
+numbers.
-The 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.
-Dividing zero by zero yields something that is not a number at all:
-@samp{+nan.0}. This is the special `not a number' value.
+Dividing by an exact zero leads to a error message, as one might expect.
+However, dividing by an inexact zero does not produce an error.
+Instead, the result of the division is either plus or minus infinity,
+depending on the sign of the divided number and the sign of the zero
+divisor (some platforms support signed zeroes @samp{-0.0} and
+@samp{+0.0}; @samp{0.0} is the same as @samp{+0.0}).
+
+Dividing zero by an inexact zero yields a @acronym{NaN} (`not a number')
+value, although they are actually considered numbers by Scheme.
+Attempts to compare a @acronym{NaN} value with any number (including
+itself) using @code{=}, @code{<}, @code{>}, @code{<=} or @code{>=}
+always returns @code{#f}. Although a @acronym{NaN} value is not
+@code{=} to itself, it is both @code{eqv?} and @code{equal?} to itself
+and other @acronym{NaN} values. However, the preferred way to test for
+them is by using @code{nan?}.
+
+The real @acronym{NaN} values and infinities are written @samp{+nan.0},
+@samp{+inf.0} and @samp{-inf.0}. This syntax is also recognized by
+@code{read} as an extension to the usual Scheme syntax. These special
+values are considered by Scheme to be inexact real numbers but not
+rational. Note that non-real complex numbers may also contain
+infinities or @acronym{NaN} values in their real or imaginary parts. To
+test a real number to see if it is infinite, a @acronym{NaN} value, or
+neither, use @code{inf?}, @code{nan?}, or @code{finite?}, respectively.
+Every real number in Scheme belongs to precisely one of those three
+classes.
On platforms that follow @acronym{IEEE} 754 for their floating point
arithmetic, the @samp{+inf.0}, @samp{-inf.0}, and @samp{+nan.0} values
They behave in arithmetic operations like @acronym{IEEE} 754 describes
it, i.e., @code{(= +nan.0 +nan.0)} @result{} @code{#f}.
-While @samp{+nan.0} is not @code{=} to itself, it is @code{eqv?} to
-itself.
-
-To test for the special values, use the functions @code{inf?} and
-@code{nan?}. To test for numbers than are neither infinite nor a NaN,
-use @code{finite?}.
-
@deffn {Scheme Procedure} real? obj
@deffnx {C Function} scm_real_p (obj)
Return @code{#t} if @var{obj} is a real number, else @code{#f}. Note
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.
@end deffn
@deffn {Scheme Procedure} rationalize x eps
@deffn {Scheme Procedure} nan
@deffnx {C Function} scm_nan ()
-Return NaN.
+Return @samp{+nan.0}, a @acronym{NaN} value.
@end deffn
@deffn {Scheme Procedure} inf
@deffnx {C Function} scm_inf ()
-Return Inf.
+Return @samp{+inf.0}, positive infinity.
@end deffn
@deffn {Scheme Procedure} numerator x
"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);
+ return scm_from_bool
+ (SCM_I_INUMP (x) || SCM_REALP (x) || SCM_BIGP (x) || SCM_FRACTIONP (x));
}
#undef FUNC_NAME
"fulfilled if @var{x} is an integer number.")
#define FUNC_NAME s_scm_rational_p
{
- 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))
+ if (SCM_I_INUMP (x) || SCM_BIGP (x) || 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. */
- return SCM_BOOL_T;
+ /* due to their limited precision, finite floating point numbers are
+ rational as well. (finite means neither infinity nor a NaN) */
+ return scm_from_bool (DOUBLE_IS_FINITE (SCM_REAL_VALUE (x)));
else
return SCM_BOOL_F;
}
"else.")
#define FUNC_NAME s_scm_integer_p
{
- double r;
- if (SCM_I_INUMP (x))
- return SCM_BOOL_T;
- if (SCM_IMP (x))
- return SCM_BOOL_F;
- if (SCM_BIGP (x))
+ if (SCM_I_INUMP (x) || SCM_BIGP (x))
return SCM_BOOL_T;
- if (!SCM_INEXACTP (x))
- return SCM_BOOL_F;
- if (SCM_COMPLEXP (x))
- return SCM_BOOL_F;
- r = SCM_REAL_VALUE (x);
- if (isinf (r))
+ else if (SCM_REALP (x))
+ {
+ double val = SCM_REAL_VALUE (x);
+ return scm_from_bool (!isinf (val) && (val == floor (val)));
+ }
+ else
return SCM_BOOL_F;
- if (r == floor (r))
- return SCM_BOOL_T;
- return SCM_BOOL_F;
}
#undef FUNC_NAME
(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")))
(pass-if (not (real? (current-input-port)))))
;;;
-;;; rational? (same as real? right now)
+;;; rational?
;;;
(with-test-prefix "rational?"
(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")))