From 8e43ed5d0bd035fae0ba106b245f03559cf529ec Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sun, 23 Jan 2011 00:06:24 +0100 Subject: [PATCH] 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. --- NEWS | 5 +++++ doc/ref/api-data.texi | 12 ++++-------- libguile/numbers.c | 9 +++++---- test-suite/tests/numbers.test | 12 ++++++++---- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/NEWS b/NEWS index f10da910f..c2bb1c142 100644 --- a/NEWS +++ b/NEWS @@ -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 diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 659dc5c0b..17b32bbd8 100755 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -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?}. diff --git a/libguile/numbers.c b/libguile/numbers.c index 21f2383ca..88b225cb2 100644 --- a/libguile/numbers.c +++ b/libguile/numbers.c @@ -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; diff --git a/test-suite/tests/numbers.test b/test-suite/tests/numbers.test index b548ad891..5ea4764e0 100644 --- a/test-suite/tests/numbers.test +++ b/test-suite/tests/numbers.test @@ -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)))) ;;; -- 2.20.1