changeset 2090:e52c5a5c6a7d

[xemacs-hg @ 2004-05-21 01:21:08 by stephent] improve bignum docs <871xled19j.fsf_-_@tleepslib.sk.tsukuba.ac.jp>
author stephent
date Fri, 21 May 2004 01:21:10 +0000
parents 7457bc074bb3
children 0221e454fe63
files man/ChangeLog man/lispref/numbers.texi
diffstat 2 files changed, 258 insertions(+), 110 deletions(-) [+]
line wrap: on
line diff
--- a/man/ChangeLog	Thu May 20 21:50:31 2004 +0000
+++ b/man/ChangeLog	Fri May 21 01:21:10 2004 +0000
@@ -1,3 +1,19 @@
+2004-05-10  Stephen J. Turnbull  <stephen@xemacs.org>
+
+	* lispref/numbers.texi (Numbers): Remove reference to "fixed-
+	precision rationals," and fix description of floating-point
+	contagion.
+	(Integer Basics, Float Basics): Fix typos.
+	(Canonicalization and Contagion): Complete rewrite.
+	(Predicates on Numbers): Add fixnump, bignump, ratiop, rationalp,
+	bigfloatp, floatingp, realp, oddp and evenp.
+	(Rational Basics): Add numerator and denominator.
+	(Random Numbers): Fix description of range, and add paranoid
+	comment about how unpredictable `(random t)' is.
+	(Canonicalization and Contagion): Renamed from Contagion and
+	Canonicalization.
+	(The Bignum Extension): Fix it in menu.
+
 2004-05-10  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* internals/internals.texi (Object-Oriented Techniques for C):
--- a/man/lispref/numbers.texi	Thu May 20 21:50:31 2004 +0000
+++ b/man/lispref/numbers.texi	Fri May 21 01:21:10 2004 +0000
@@ -5,6 +5,7 @@
 @setfilename ../../info/numbers.info
 @node Numbers, Strings and Characters, Lisp Data Types, Top
 @chapter Numbers
+@c #### Improve the indexing in this file!!!!
 @cindex integers
 @cindex numbers
 
@@ -33,25 +34,32 @@
 and back, depending on the storage required to represent the number.
 Thus use of bignums are entirely transparent to the user, except for a
 few special applications that expect overflows.  Ratios are rational
-numbers with arbitrary precision.  (In theory fixed-size rationals could
-be supported, but for almost all applications floats are a reasonable
-substitute for fixed-precision rationals.)  They are notated in the
-usual way with the solidus, for example 5/3 or @minus{}22/7.  Bigfloats
-are floating point numbers with arbitrary precision.  Unlike integers,
-which are always infinitely precise if they can be represented, floating
-point numbers are inherently imprecise.  Therefore XEmacs automatically
-converts @emph{from float to bigfloat} when floats and bigfloats are
-mixed in an expression, but a bigfloat will never be converted to a
-float unless the user explicitly coerces the value.  Nor will the result
-of a float operation be converted to bigfloat, except for ``contagion''
-from another operand that is already a bigfloat.
+numbers with arbitrary precision.  They are notated in the
+usual way with the solidus, for example 5/3 or @minus{}22/7.
+
+  Bigfloats are floating point numbers with arbitrary precision, which
+may be specified by the user (and may be different for different
+bigfloats at the same time).  Unlike integers, which are always
+infinitely precise if they can be represented, floating point numbers
+are inherently imprecise.  This means that choice of precision can be a
+very delicate issue.  XEmacs automatically converts @emph{from float to
+bigfloat} when floats and bigfloats are mixed in an expression, but a
+bigfloat will never be converted to a float unless the user explicitly
+coerces the value.  Nor will the result of a float operation be
+converted to bigfloat, except for ``contagion'' from another operand
+that is already a bigfloat.  However, when bigfloats of differing
+precision are mixed, the result will always have the larger precision.
+The exact rules are more carefully explained elsewhere
+(@pxref{Canonicalization and Contagion}).
 
   Note that the term ``integer'' is used throughout the XEmacs
 documentation and code to mean ``fixnum''.  This is inconsistent with
 Common Lisp, and likely to cause confusion.  Similarly, ``float'' is
 used to mean ``fixed precision floating point number'', and the Common
-Lisp distinctions among @dfn{short-floats}, @dfn{long-floats}, and
-bigfloats are not reflected in XEmacs terminology.
+Lisp distinctions among @dfn{short-floats}, @dfn{long-floats},
+@emph{etc.}, and bigfloats (which are not standardized in Common Lisp)
+are not reflected in XEmacs terminology.  (Volunteers to fix this in the
+XEmacs manuals would be heartily welcomed.)
 
 @menu
 * Integer Basics::            Representation and range of integers.
@@ -73,7 +81,7 @@
 
   The range of values for an integer depends on the machine.    If a
 multiple-precision arithmetic library is available on your platform,
-support for bignums, that is, integers with arbitrary precision, maybe
+support for bignums, that is, integers with arbitrary precision, may be
 compiled in to your XEmacs.  The rest of this section assumes that the
 bignum extension is @emph{not} available.  The bignum extension and the
 user-visible differences in normal integer arithmetic are discussed in a
@@ -198,7 +206,22 @@
 Ratios (built-in rational numbers) are available only when the bignum
 extension is built into your XEmacs.  This facility is new and
 experimental.  It is discussed in a separate section for convenience of
-updating the documentation @ref{The Bignum Extension}.
+updating the documentation @ref{The Bignum Extension}.  The following
+functions are defined regardless of the presence of the extension, but
+have trivial results for integers.
+
+@defun numerator rational
+@cindex numbers
+Return the numerator of the canonical form of @var{rational}.
+If @var{rational} is an integer, @var{rational} is returned.
+@var{rational} must be an integer or a ratio.
+@end defun
+
+@defun denominator rational
+Return the denominator of the canonical form of @var{rational}.
+If @var{rational} is an integer, 1 is returned.  @var{rational} must be
+an integer or a ratio.
+@end defun
 
 
 @node Float Basics
@@ -209,7 +232,7 @@
 data type @code{double} on the machine in question.  If a
 multiple-precision arithmetic library is available on your platform,
 support for bigfloats, that is, floating point numbers with arbitrary
-precision, maybe compiled in to your XEmacs.  The rest of this section
+precision, may be compiled in to your XEmacs.  The rest of this section
 assumes that the bignum extension is @emph{not} available.  The bigfloat
 extension and the user-visible differences in normal float arithmetic
 are discussed in a separate section @ref{The Bignum Extension}.
@@ -316,22 +339,28 @@
 is often the case with Linux distributions for 80x86, you may achieve
 gains of @emph{several orders of magnitude} by rebuilding the MP
 library.  See @uref{http://www.swox.com/gmp/gmp-speed.html}.)  The MP
-implementation provides arbitrary precision integers, but ratios were
-implemented by the XEmacs implementer, Jerry James, who is not a
-numerical analyst.  Arbitrary precision floats are not available with
-MP.
+implementation provides arbitrary precision integers.  Ratios and arbitrary
+precision floats are not available with MP.
 
   If your code needs to run correctly whether or not the feature is
 provided, you may test for the features @code{bignum}, @code{ratio}, and
 @code{bigfloat}.
 
-  The XEmacs bignum facility implements the Common Lisp notion of
-@dfn{contagion}, so that integers are always represented using the
-``smallest'' representation that is exact, and integral ratios are
-converted to integers.  Since floating point arithmetic is inherently
-imprecise, numbers are implicitly coerced to bigfloats only if other
-operands in the expression are bigfloat, and bigfloats are only coerced
-to other numerical types by explicit calls to the function @code{coerce}.
+  The XEmacs bignum facility implements the Common Lisp notions of
+@dfn{canonicalization} and @dfn{contagion}.  Canonicalization means that
+in exact (integer and ratio) arithmetic, a result of an operation is
+always converted to the ``smallest'' type that can represent it
+exactly.  For exact numbers, the user only cares if efficiency is
+extremely important; Lisp does not try to determine an order of
+computation that avoids conversion to bignum (or ratio) even if one is
+available.  (Note that integers are never silently converted to
+ratios: the result of @code{(/ 1 2)} is the integer @code{0}.  You can
+@emph{request} that a ratio be used if needed with @code{(div 1 2)}.)
+
+  Since floating point arithmetic is inherently imprecise, numbers are
+implicitly coerced to bigfloats only if other operands in the expression
+are bigfloat, and bigfloats are only coerced to other numerical types by
+explicit calls to the function @code{coerce}.
 
   Bignum support is incomplete.  If you would like to help with bignum
 support, especially on BSD MP, please subscribe to the
@@ -345,7 +374,7 @@
 * Bignum Basics::             Representation and range of integers.
 * Ratio Basics::              Representation and range of rational numbers.
 * Bigfloat Basics::           Representation and range of floating point.
-* Contagion and Canonicalization::  Automatic coercion to other types.
+* Canonicalization and Contagion::  Automatic coercion to other types.
 * Compatibility Issues::      Changes in fixed-precision arithmetic.
 @end menu
 
@@ -380,39 +409,58 @@
 representations as fixed-precision floats.
 
 
-@node Contagion and Canonicalization
-@subsection Contagion
+@node Canonicalization and Contagion
+@subsection Canonicalization and Contagion
+
+@dfn{Canonicalization} is a rule intended to enhance the time and space
+efficiency of exact arithmetic.  Because bignums and ratios are
+implemented as record objects, they take up much more space than
+fixnums, which are implemented as an immediate object.  Conversions and
+calls to the MP library also take time.  So the implementation always
+converts the result of exact arithmetic to the smallest representation
+that can exactly represent the quantity.
+
+@example
+(+ 3/4 5)
+    @result{} 23/4
+
+(+ 3/4 1/4 2)
+    @result{} 3
+@end example
+
+Conversely, if an integer (read or computed) cannot be represented as a
+fixnum, a bignum will be used.  Integer division is a somewhat
+exceptional case.  Because it is useful and is the historical meaning of
+the function @code{/}, a separate function @code{div} is provided.
+@code{div} is identical to @code{/} except that when the rational result
+is not an integer, it is represented exactly as a ratio.  In both cases
+if a rational result is an integer, it is automatically converted to the
+appropriate integral representation.
+
+  Note that the efficiency gain from canonicalization is likely to be
+less than you might think. Experience with numerical analysis shows that
+in very precise calculations, the required precision tends to increase.
+Thus it is typically wasted effort to attempt to convert to smaller
+representations, as the number is often reused and requires a larger
+representation.  However, XEmacs Lisp presumes that calculations using
+bignums are the exception, so it applies canonicalization.
 
 @dfn{Contagion} is one way to address the requirement that an arithmetic
-operation should not fail because of differing types of the operands, or
-insufficient precision in the representation.  With bignum support, we
-can represent @code{(+ most-positive-fixnum most-positive-fixnum)} (or
-@code{(* most-positive-fixnum most-positive-fixnum)}, for that matter)
-@emph{exactly}.  There should be no overflow or ``wrap-around,'' and the
-computation should not be interrupted by an error.  Contagion is the
-idea that less precise operands are converted to the more precise type,
-and then the operation is performed.  This involves no loss of
-information, and therefore it is safe to do it automatically.
+operation should not fail because of differing types of the operands.
+Contagion is the idea that less precise operands are converted to the
+more precise type, and then the operation is performed.  While changing
+precision is a delicate issue, contagion is so useful that XEmacs
+performs it automatically.
 
 In XEmacs, the following rules of contagion are used:
 
 @c #### this probably wants names for each rule
 @enumerate
 @item
-If a fixnum operation would overflow or underflow, the operands are
-promoted to bignums and the operation is performed.
-
-@item
-If a fixnum and a bignum are the operands, the fixnum is promoted to
-bignum, and the operation is performed.
+If an expression mixes an integral type with a ratio, then the usual
+rules of rational arithmetic apply.  (If the result of the expression
+happens to be an integer, it will be canonicalized to integer.)
 
-@c #### seems plausible
-@item
-If a float operation would overflow or underflow (@emph{i.e.}, produce
-an unrepresentably small but non-zero result), the operands are
-converted to bigfloats and the operation performed.
-
-@c #### seems likely....
 @item
 If an expression mixes a rational type (fixnum, bignum, or ratio) with a
 float, the rational operand is converted to a float and the operation
@@ -422,35 +470,10 @@
 @item
 If an expression mixes any other type with a bigfloat, the other operand
 is converted to bigfloat and the operation performed.
-@end enumerate
-
-Note that there is @emph{no} contagion with ratios.  Integer-to-integer
-arithmetic with truncation or rounding is useful, and familiar.
-Therefore instead of converting the result of @code{/} to ratio if it is
-non-integral, the traditional definition is maintained, and a new
-function @code{div} is provided to give a ratio result if a division
-does not come out evenly.
-
-On the other hand, the representation of arbitrary precision numbers is
-inefficient in both space and time.  The principle of
-@dfn{canonicalization} addresses this issue.  The idea of
-canonicalization is that when no information is lost, the representation
-should be demoted to the more efficient (smaller) representation.  Note
-that the inefficiency is likely to be greater than you might think.
-Experience with numerical analysis shows that in very precise
-calculations, precision tends to increase.  Thus it is typically wasted
-effort to attempt to convert to smaller representations, as the number
-is often reused and requires a larger representation.  However, XEmacs
-Lisp presumes that calculations using bignums are the exception, so it
-applies canonicalization.  The rules are
-
-@enumerate
-@item
-If a ratio is integral, demote it to a bignum.  (In XEmacs Lisp all
-ratios are arbitrary precision numbers.)
 
 @item
-If a bignum is small enough to fit in a fixnum, demote it to fixnum.
+If bigfloats of different precision are mixed, all are converted to the
+@emph{highest} precision, and the operation performed.
 @end enumerate
 
 Note that there are no rules to canonicalize floats or bigfloats.  This
@@ -472,6 +495,10 @@
 Return the canonical form of @var{number}.
 @end defun
 
+However, if we've done our job properly, this is always a no-op.  That
+is, if you find a number in un-canonicalized form, please report it as a
+bug.
+
 
 @node Compatibility Issues
 @subsection Compatibility Issues
@@ -542,19 +569,32 @@
 @section Type Predicates for Numbers
 
   The functions in this section test whether the argument is a number or
-whether it is a certain sort of number.  The functions @code{integerp}
-and @code{floatp} can take any type of Lisp object as argument (the
-predicates would not be of much use otherwise); but the @code{zerop}
-predicate requires a number as its argument.  See also
-@code{integer-or-marker-p}, @code{integer-char-or-marker-p},
-@code{number-or-marker-p} and @code{number-char-or-marker-p}, in
-@ref{Predicates on Markers}.
+whether it is a certain sort of number.  The functions which test for
+type can take any type of Lisp object as argument (the more general
+predicates would not be of much use otherwise).  However, the
+@code{zerop} predicate requires a number as its argument, and the
+@code{evenp}, and @code{oddp} predicates require integers as their
+arguments.  See also @code{integer-or-marker-p},
+@code{integer-char-or-marker-p}, @code{number-or-marker-p} and
+@code{number-char-or-marker-p}, in @ref{Predicates on Markers}.
 
-@defun floatp object
-This predicate tests whether its argument is a floating point
-number and returns @code{t} if so, @code{nil} otherwise.
+@defun numberp object
+This predicate tests whether its argument is a number (either integer or
+floating point), and returns @code{t} if so, @code{nil} otherwise.
+@end defun
 
-@code{floatp} does not exist in Emacs versions 18 and earlier.
+@defun realp object
+@cindex numbers
+The @code{realp} predicate tests to see whether @var{object} is a
+rational or floating point number, and returns @code{t} if so,
+@code{nil} otherwise.  Currently equivalent to @code{numberp}.
+@end defun
+
+@defun zerop number
+This predicate tests whether its argument is zero, and returns @code{t}
+if so, @code{nil} otherwise.  The argument must be a number.
+
+These two forms are equivalent: @code{(zerop x)} @equiv{} @code{(= x 0)}.
 @end defun
 
 @defun integerp object
@@ -562,9 +602,18 @@
 @code{t} if so, @code{nil} otherwise.
 @end defun
 
-@defun numberp object
-This predicate tests whether its argument is a number (either integer or
-floating point), and returns @code{t} if so, @code{nil} otherwise.
+@defun oddp integer
+@cindex integers
+The @code{oddp} predicate tests to see whether @var{integer} is odd, and
+returns @code{t} if so, @code{nil} otherwise.  @var{integer} must be an
+integer.
+@end defun
+
+@defun evenp integer
+@cindex integers
+The @code{evenp} predicate tests to see whether @var{integer} is even,
+and returns @code{t} if so, @code{nil} otherwise.  @var{integer} must be
+an integer.
 @end defun
 
 @defun natnump object
@@ -575,23 +624,67 @@
 considered non-negative.
 @end defun
 
-@defun zerop number
-This predicate tests whether its argument is zero, and returns @code{t}
-if so, @code{nil} otherwise.  The argument must be a number.
+@defun fixnump object
+@cindex integers
+The @code{} predicate tests to see whether its argument is an integer
+represented as a fixnum, and returns @code{t} if so, @code{nil}
+otherwise.
+@end defun
+
+@defun bignump object
+@cindex integers
+The @code{bignump} predicate tests to see whether @var{object} is an
+integer represented as a bignum, and returns @code{t} if so, @code{nil}
+otherwise.
+@end defun
+
+@defun rationalp object
+@cindex numbers
+The @code{rationalp} predicate tests to see whether @var{object} is a
+rational number, and returns @code{t} if so, @code{nil} otherwise.
+@end defun
 
-These two forms are equivalent: @code{(zerop x)} @equiv{} @code{(= x 0)}.
+@defun ratiop object
+@cindex ratios
+The @code{ratiop} predicate tests to see whether @var{object} is a
+number represented as a ratio, and returns @code{t} if so, @code{nil}
+otherwise.
+@end defun
+
+@defun floatingp object
+@cindex floats
+The @code{floatingp} predicate tests to see whether @var{object} is a
+floating point number represented as a float or a bigfloat, and returns
+@code{t} if so, @code{nil} otherwise.
 @end defun
 
+@defun floatp object
+@cindex floats
+This predicate tests whether its argument is a floating point
+number and returns @code{t} if so, @code{nil} otherwise.
+
+@code{floatp} does not exist in Emacs versions 18 and earlier.  If the
+bignum extension is present, it returns @code{nil} for a bigfloat.
+@end defun
+
+@defun bigfloatp object
+@cindex floats
+The @code{bigfloatp} predicate tests to see whether @var{object} is an
+integer represented as a fixnum, and returns @code{t} if so, @code{nil}
+otherwise.
+@end defun
+
+
 @node Comparison of Numbers
 @section Comparison of Numbers
 @cindex number equality
 
   To test numbers for numerical equality, you should normally use
-@code{=}, not @code{eq}.  There can be many distinct floating point
-number objects with the same numeric value.  If you use @code{eq} to
-compare them, then you test whether two values are the same
-@emph{object}.  By contrast, @code{=} compares only the numeric values
-of the objects.
+@code{=}, not @code{eq}.  There can be many distinct floating point,
+bignum, and ratio number objects with the same numeric value.  If you
+use @code{eq} to compare them, then you test whether two values are the
+same @emph{object}.  By contrast, @code{=} compares only the numeric
+values of the objects.
 
   In versions before 21.5.18, each integer value had a unique Lisp
 object in XEmacs Lisp.  Therefore, @code{eq} was equivalent to @code{=}
@@ -604,6 +697,39 @@
 for comparing exact values, because two bignums or ratios with the same
 value will often not be the same object.
 
+On the other hand, some functions, such as the string- and
+buffer-searching functions, will return an integer on success, but
+something else (usually @code{nil}) on failure.  If it is known what the
+numerical subtype (float, bigfloat, or exact) of the returned object
+will be if it is a number, then the predicate @code{eql} can be used for
+comparison without signaling an error on some expected return values.
+Because of canonicalization, @code{eql} can be used to compare a fixnum
+value to something that might be a ratio; if the potential ratio value
+is representable as a fixnum, it will be canonicalized to fixnum before
+comparing.
+
+@example
+(eql 2 (string-match "ere" "there"))
+    @result{} t
+
+(eql 2 (string-match "ere" "three"))
+    @result{} nil
+
+(eql 2 2.0)
+    @result{} nil
+
+(= 2 (string-match "ere" "there"))
+    @result{} t
+
+(= 2 (string-match "ere" "three"))
+    @error{} Wrong type argument: number-char-or-marker-p, nil
+
+(= 2 2.0)
+    @result{} t
+@end example
+
+
+
   There is another wrinkle: because floating point arithmetic is not
 exact, it is often a bad idea to check for equality of two floating
 point values.  Usually it is better to test for approximate equality.
@@ -1444,9 +1570,11 @@
 -1457731, and the second one always returns -7692030.  This
 repeatability is helpful for debugging.
 
-If you want truly unpredictable random numbers, execute @code{(random
-t)}.  This chooses a new seed based on the current time of day and on
-XEmacs's process @sc{id} number.
+If you want reasonably unpredictable random numbers, execute
+@code{(random t)}.  This chooses a new seed based on the current time of
+day and on XEmacs's process @sc{id} number.  (This is not
+cryptographically strong, it's just hard for a @emph{human} to
+anticipate.)
 
 @defun random &optional limit
 This function returns a pseudo-random integer.  Repeated calls return a
@@ -1458,8 +1586,12 @@
 If @var{limit} is @code{t}, it means to choose a new seed based on the
 current time of day and on XEmacs's process @sc{id} number.
 @c "XEmacs'" is incorrect usage!
+@end defun
 
-On some machines, any integer representable in Lisp may be the result
-of @code{random}.  On other machines, the result can never be larger
-than a certain maximum or less than a certain (negative) minimum.
-@end defun
+The range of random is implementation-dependent.  On any machine, the
+result of @code{(random)} is an arbitrary fixnum, so on 32-bit
+architectures it is normally in the range -2^30 (inclusive) to +2^30
+(exclusive).  With the optional integer argument @var{limit}, the result
+is in the range 0 (inclusive) to @var{limit} (exclusive).  Note this is
+regardless of the presence of the bignum extension.
+