Mercurial > hg > xemacs-beta
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. +