infinities are no longer integers

* libguile/numbers.c (scm_is_integer): Infinities are not integers, per
  the R6RS.
  (scm_even_p, scm_odd_p): Passing an infinity to even? or odd? is an
  error.

* test-suite/tests/numbers.test ("integer?"): Adapt test.
  ("expt"): Add tests for +inf.0 and -inf.0 exponents.

* NEWS: Add NEWS entries.
This commit is contained in:
Andy Wingo 2011-01-23 00:06:24 +01:00
commit 8e43ed5d0b
4 changed files with 22 additions and 16 deletions

5
NEWS
View file

@ -10,6 +10,11 @@ latest prerelease, and a full NEWS corresponding to 1.8 -> 2.0.
Changes in 1.9.15 (since the 1.9.14 prerelease):
** Infinities are no longer integers.
Following the R6RS, infinities (+inf.0 and -inf.0) are no longer
considered to be integers.
** New reader option: `hungry-eol-escapes'
Guile's string syntax is more compatible with R6RS when the

View file

@ -303,10 +303,6 @@ representation where the required number does not fit in the native
form. Conversion between these two representations is automatic and
completely invisible to the Scheme level programmer.
The infinities @samp{+inf.0} and @samp{-inf.0} are considered to be
inexact integers. They are explained in detail in the next section,
together with reals and rationals.
C has a host of different integer types, and Guile offers a host of
functions to convert between them and the @code{SCM} representation.
For example, a C @code{int} can be handled with @code{scm_to_int} and
@ -537,7 +533,8 @@ infinity, depending on the sign of the divided number.
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.
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.
@ -548,9 +545,8 @@ are implemented using the corresponding @acronym{IEEE} 754 values.
They behave in arithmetic operations like @acronym{IEEE} 754 describes
it, i.e., @code{(= +nan.0 +nan.0)} @result{} @code{#f}.
The infinities are inexact integers and are considered to be both even
and odd. While @samp{+nan.0} is not @code{=} to itself, it is
@code{eqv?} to itself.
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?}.

View file

@ -1,4 +1,4 @@
/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
*
* Portions Copyright 1990, 1991, 1992, 1993 by AT&T Bell Laboratories
* and Bellcore. See scm_divide.
@ -530,7 +530,7 @@ SCM_DEFINE (scm_odd_p, "odd?", 1, 0, 0,
return scm_from_bool (odd_p);
}
else if (scm_is_true (scm_inf_p (n)))
return SCM_BOOL_T;
SCM_WRONG_TYPE_ARG (1, n);
else if (SCM_REALP (n))
{
double rem = fabs (fmod (SCM_REAL_VALUE(n), 2.0));
@ -565,7 +565,7 @@ SCM_DEFINE (scm_even_p, "even?", 1, 0, 0,
return scm_from_bool (even_p);
}
else if (scm_is_true (scm_inf_p (n)))
return SCM_BOOL_T;
SCM_WRONG_TYPE_ARG (1, n);
else if (SCM_REALP (n))
{
double rem = fabs (fmod (SCM_REAL_VALUE(n), 2.0));
@ -3333,7 +3333,8 @@ SCM_DEFINE (scm_integer_p, "integer?", 1, 0, 0,
if (SCM_COMPLEXP (x))
return SCM_BOOL_F;
r = SCM_REAL_VALUE (x);
/* +/-inf passes r==floor(r), making those #t */
if (isinf (r))
return SCM_BOOL_F;
if (r == floor (r))
return SCM_BOOL_T;
return SCM_BOOL_F;

View file

@ -1,5 +1,5 @@
;;;; numbers.test --- tests guile's numbers -*- scheme -*-
;;;; Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2009, 2010 Free Software Foundation, Inc.
;;;; Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006, 2009, 2010, 2011 Free Software Foundation, Inc.
;;;;
;;;; This library is free software; you can redistribute it and/or
;;;; modify it under the terms of the GNU Lesser General Public
@ -1508,8 +1508,8 @@
(pass-if (and (= 3+0i (round 3+0i)) (integer? 3+0i)))
(pass-if (and (= 1.0 (round 1.0)) (integer? 1.0)))
(pass-if (not (integer? 1.3)))
(pass-if (integer? +inf.0))
(pass-if (integer? -inf.0))
(pass-if (not (integer? +inf.0)))
(pass-if (not (integer? -inf.0)))
(pass-if (not (integer? +nan.0)))
(pass-if (not (integer? 3+4i)))
(pass-if (not (integer? #\a)))
@ -2949,7 +2949,11 @@
(pass-if (eqv? (* -1.0 12398 12398) (expt +12398i 2.0)))
(pass-if (eqv-loosely? +i (expt -1 0.5)))
(pass-if (eqv-loosely? +i (expt -1 1/2)))
(pass-if (eqv-loosely? 1.0+1.7320508075688i (expt -8 1/3))))
(pass-if (eqv-loosely? 1.0+1.7320508075688i (expt -8 1/3)))
(pass-if (eqv? +inf.0 (expt 2 +inf.0)))
(pass-if (eqv? +inf.0 (expt 2.0 +inf.0)))
(pass-if (eqv? 0.0 (expt 2 -inf.0)))
(pass-if (eqv? 0.0 (expt 2.0 -inf.0))))
;;;