1
0
Fork 0
cl-sites/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node130.html
2023-10-25 11:23:21 +02:00

402 lines
20 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3O//DTD W3 HTML 2.0//EN">
<!Converted with LaTeX2HTML 0.6.5 (Tue Nov 15 1994) by Nikos Drakos (nikos@cbl.leeds.ac.uk), CBLU, University of Leeds >
<HEAD>
<TITLE>12.6. Type Conversions and Component Extractions on Numbers</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" Type Conversions and Component Extractions on Numbers">
<meta name="keywords" value="clm">
<meta name="resource-type" value="document">
<meta name="distribution" value="global">
<P>
<b>Common Lisp the Language, 2nd Edition</b>
<BR> <HR><A NAME=tex2html3151 HREF="node131.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3149 HREF="node121.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3143 HREF="node129.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3153 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3154 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3152 HREF="node131.html"> Logical Operations on </A>
<B>Up:</B> <A NAME=tex2html3150 HREF="node121.html"> Numbers</A>
<B> Previous:</B> <A NAME=tex2html3144 HREF="node129.html"> Branch CutsPrincipal </A>
<HR> <P>
<H1><A NAME=SECTION001660000000000000000>12.6. Type Conversions and Component Extractions on Numbers</A></H1>
<P>
While most arithmetic functions will operate on any kind of number,
coercing types if necessary, the following functions are provided to
allow specific conversions of data types to be forced when desired.
<P>
<BR><b>[Function]</b><BR>
<tt>float <i>number</i> &amp;optional <i>other</i></tt><P>This converts any non-complex number to a floating-point number.
With no second argument, if <i>number</i> is already a floating-point
number, then <i>number</i> is returned;
otherwise a <tt>single-float</tt> is produced.
If the argument <i>other</i> is provided, then it must be a floating-point
number, and <i>number</i> is converted to the same format as <i>other</i>.
See also <tt>coerce</tt>.
<P>
<BR><b>[Function]</b><BR>
<tt>rational <i>number</i> <BR></tt><tt>rationalize <i>number</i></tt><P>Each of these functions converts any non-complex number to a rational
number. If the argument is already rational, it is returned.
The two functions differ in their treatment of floating-point numbers.
<P>
<tt>rational</tt> assumes that the floating-point number is completely accurate
and returns a rational number mathematically equal to the precise
value of the floating-point number.
<P>
<tt>rationalize</tt> assumes that the
floating-point number is accurate only to the precision of the
floating-point representation and may return any rational number for
which the floating-point number is the best available approximation of
its format; in doing this it attempts to keep both numerator and
denominator small.
<P>
It is always the case that
<P><pre>
(float (rational <i>x</i>) <i>x</i>) == <i>x</i>
</pre><P>
and
<P><pre>
(float (rationalize <i>x</i>) <i>x</i>) == <i>x</i>
</pre><P>
That is, rationalizing a floating-point number by either method
and then converting it back
to a floating-point number of the same format produces the original number.
What distinguishes the two functions is that <tt>rational</tt> typically
has a simple, inexpensive implementation, whereas <tt>rationalize</tt> goes
to more trouble to produce a result that is more pleasant to view and
simpler to compute with for some purposes.
<P>
<BR><b>[Function]</b><BR>
<tt>numerator <i>rational</i> <BR></tt><tt>denominator <i>rational</i></tt><P>These functions take a rational number (an integer or ratio)
and return as an integer the numerator or denominator of the canonical
reduced form of the rational. The numerator of an integer is that integer;
the denominator of an integer is <tt>1</tt>. Note that
<P><pre>
(gcd (numerator <i>x</i>) (denominator <i>x</i>)) => 1
</pre><P>
The denominator will always be a strictly positive integer;
the numerator may be any integer.
For example:
<P><pre>
(numerator (/ 8 -6)) => -4
(denominator (/ 8 -6)) => 3
</pre><P>
<P>
There is no <tt>fix</tt> function in Common Lisp because there are several
interesting ways to convert non-integral values to integers.
These are provided by the functions below, which perform not only
type conversion but also some non-trivial calculations as well.
<P>
<BR><b>[Function]</b><BR>
<tt>floor <i>number</i> &amp;optional <i>divisor</i> <BR></tt><tt>ceiling <i>number</i> &amp;optional <i>divisor</i> <BR></tt><tt>truncate <i>number</i> &amp;optional <i>divisor</i> <BR></tt><tt>round <i>number</i> &amp;optional <i>divisor</i></tt><P>In the simple one-argument case,
each of these functions converts its argument <i>number</i>
(which must not be complex) to an integer.
If the argument is already an integer, it is returned directly.
If the argument is a ratio or floating-point number, the functions use
different algorithms for the conversion.
<P>
<tt>floor</tt> converts its argument by truncating toward negative
infinity; that is, the result is the largest integer that is not larger
than the argument.
<P>
<tt>ceiling</tt> converts its argument by truncating toward positive
infinity; that is, the result is the smallest integer that is not smaller
than the argument.
<P>
<tt>truncate</tt> converts its argument by truncating toward zero;
that is, the result is the integer of the same sign as the argument
and which has the greatest integral
magnitude not greater than that of the argument.
<P>
<tt>round</tt> converts its argument by rounding to the nearest
integer; if <i>number</i> is exactly halfway between two integers
(that is, of the form <i>integer</i>+0.5), then it is rounded to the one that
is even (divisible by 2).
<P>
The following table shows what the four functions produce when given
various arguments.
<P>
<pre>
Argument floor ceiling truncate round
----------------------------------------------------------
2.6 2 3 2 3
2.5 2 3 2 2
2.4 2 3 2 2
0.7 0 1 0 1
0.3 0 1 0 0
-0.3 -1 0 0 0
-0.7 -1 0 0 -1
-2.4 -3 -2 -2 -2
-2.5 -3 -2 -2 -2
-2.6 -3 -2 -2 -3
----------------------------------------------------------
</pre>
If a second argument <i>divisor</i> is supplied, then the result
is the appropriate type of rounding or truncation applied to the
result of dividing the <i>number</i> by the <i>divisor</i>.
For example, <tt>(floor 5 2)</tt> == <tt>(floor (/ 5 2))</tt> but is potentially more
efficient.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
This statement is not entirely accurate; one should instead say that
<tt>(values (floor 5 2))</tt> == <tt>(values (floor (/ 5 2)))</tt>,
because there is a second value to consider, as discussed below.
In other words, the first values returned by the two forms will be the same, but
in general the second values will differ. Indeed, we have
<P><pre>
(floor 5 2) => 2 and 1
(floor (/ 5 2)) => 2 and 1/2
</pre><P>
for this example.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
The <i>divisor</i> may be any non-complex number.
<p>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
It is generally accepted that it is an error for the <i>divisor</i> to be zero.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
The one-argument case is exactly like the two-argument case where the second
argument is <tt>1</tt>.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
In other words, the one-argument case returns an integer and fractional part
for the <i>number</i>: <tt>(truncate 5.3) => 5.0 and 0.3</tt>, for example.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
Each of the functions actually returns <i>two</i> values,
whether given one or two arguments. The second
result is the remainder and may be obtained using
<tt>multiple-value-bind</tt> and related constructs.
If any of these functions is given two arguments <b><i>x</i></b> and <b><i>y</i></b>
and produces results <b><i>q</i></b> and <b><i>r</i></b>, then <b><i>q</i> <i>y</i>+<i>r</i>=<i>x</i></b>.
The first result <b><i>q</i></b> is always an integer.
The remainder <b><i>r</i></b> is an integer if both arguments are integers,
is rational if both arguments are rational,
and is floating-point if either argument is floating-point.
One consequence is that
in the one-argument case the remainder is always a number of the same type
as the argument.
<P>
When only one argument is given, the two results are exact;
the mathematical sum of the two results is always equal to the
mathematical value of the argument.
<P>
<hr>
<b>Compatibility note:</b> The names of the functions <tt>floor</tt>, <tt>ceiling</tt>,
<tt>truncate</tt>, and <tt>round</tt> are more accurate than names like <tt>fix</tt>
that have heretofore been used in various Lisp systems.
The names used here are compatible with standard mathematical
terminology (and with PL/1, as it happens). In Fortran
<tt>ifix</tt> means <tt>truncate</tt>. Algol 68 provides <tt>round</tt>
and uses <tt>entier</tt> to mean <tt>floor</tt>.
In MacLisp, <tt>fix</tt> and <tt>ifix</tt> both
mean <tt>floor</tt> (one is generic, the other flonum-in/fixnum-out).
In Interlisp, <tt>fix</tt> means <tt>truncate</tt>.
In Lisp Machine Lisp, <tt>fix</tt> means <tt>floor</tt> and <tt>fixr</tt> means <tt>round</tt>.
Standard Lisp provides a <tt>fix</tt> function but does not
specify precisely what it does. The existing usage
of the name <tt>fix</tt> is so confused that it seemed best to avoid it
altogether.
<P>
The names and definitions given here have recently been adopted
by Lisp Machine Lisp, and MacLisp and NIL (New Implementation of Lisp) seem likely to follow suit.
<hr>
<P>
<BR><b>[Function]</b><BR>
<tt>mod <i>number</i> <i>divisor</i> <BR></tt><tt>rem <i>number</i> <i>divisor</tt><P><tt>mod</tt></i> performs the operation <tt>floor</tt> on its two arguments
and returns the <i>second</i> result of <tt>floor</tt> as its only result.
Similarly,
<tt>rem</tt> performs the operation <tt>truncate</tt> on its arguments
and returns the <i>second</i> result of <tt>truncate</tt> as its only result.
<P>
<tt>mod</tt> and <tt>rem</tt> are therefore the usual modulus
and remainder functions when applied to two integer arguments.
In general, however, the arguments may be integers or floating-point
numbers.
<pre>
(mod 13 4) => 1 (rem 13 4) => 1
(mod -13 4) => 3 (rem -13 4) => -1
(mod 13 -4) => -3 (rem 13 -4) => 1
(mod -13 -4) => -1 (rem -13 -4) => -1
(mod 13.4 1) => 0.4 (rem 13.4 1) => 0.4
(mod -13.4 1) => 0.6 (rem -13.4 1) => -0.4
</pre>
<hr>
<b>Compatibility note:</b> The Interlisp function <tt>remainder</tt> is essentially
equivalent to the Common Lisp function <tt>rem</tt>. The MacLisp function <tt>remainder</tt>
is like <tt>rem</tt> but accepts only integer arguments.
<hr>
<P>
<BR><b>[Function]</b><BR>
<tt>ffloor <i>number</i> &amp;optional <i>divisor</i> <br>
</tt><tt>fceiling <i>number</i> &amp;optional <i>divisor</i> <br>
</tt><tt>ftruncate <i>number</i> &amp;optional <i>divisor</i> <br>
</tt><tt>fround <i>number</i> &amp;optional <i>divisor</i></tt>
<P>These functions are just like <tt>floor</tt>, <tt>ceiling</tt>, <tt>truncate</tt>, and
<tt>round</tt>, except that the result (the first result of two) is always a
floating-point number rather than an integer. It is roughly as if
<tt>ffloor</tt> gave its arguments to <tt>floor</tt>, and then applied <tt>float</tt> to
the first result before passing them both back. In practice, however,
<tt>ffloor</tt> may be implemented much more efficiently. Similar remarks
apply to the other three functions. If the first argument is a
floating-point number, and the second argument is not a floating-point
number of longer format, then the first result will be a floating-point
number of the same type as the first argument.
For example:
<P><pre>
(ffloor -4.7) => -5.0 and 0.3
(ffloor 3.5d0) => 3.0d0 and 0.5d0
</pre><P>
<P>
<BR><b>[Function]</b><BR>
<tt>decode-float <i>float</i> <BR></tt><tt>scale-float <i>float</i> <i>integer</i> <BR></tt><tt>float-radix <i>float</i> <BR></tt><tt>float-sign <i>float1</i> &amp;optional <i>float2</i> <BR></tt><tt>float-digits <i>float</i> <BR></tt><tt>float-precision <i>float</i> <BR></tt><tt>integer-decode-float <i>float</i></tt><P>The function <tt>decode-float</tt> takes a floating-point number
and returns three values.
<P>
The first value is a new floating-point number of the same format
representing the significand; the second value is an integer
representing the exponent; and the third value is a floating-point
number of the same format indicating the sign (-1.0 or 1.0).
Let <i>b</i> be the radix for the floating-point representation;
then <tt>decode-float</tt> divides the argument by an integral power of <i>b</i>
so as to bring its value between 1/<i>b</i> (inclusive) and 1 (exclusive)
and returns the quotient as the first value.
If the argument is zero, however, the result
is equal to the absolute value of the argument (that is, if there is a negative
zero, its significand is considered to be a positive zero).
<P>
The second value of <tt>decode-float</tt> is
the integer exponent <i>e</i> to which <i>b</i> must be raised
to produce the appropriate power for the division.
If the argument is zero, any integer value may be returned, provided
that the identity shown below for <tt>scale-float</tt> holds.
<P>
The third value of <tt>decode-float</tt> is a floating-point number,
of the same format as the argument, whose absolute value is 1
and whose sign matches that of the argument.
<P>
The function <tt>scale-float</tt> takes a floating-point number <i>f</i>
(not necessarily between 1/<i>b</i> and 1) and
an integer <i>k</i>, and returns <tt>(* <i>f</i> (expt (float <i>b</i> <i>f</i>) <i>k</i>))</tt>.
(The use of <tt>scale-float</tt> may be much more efficient than using
exponentiation and multiplication and avoids intermediate
overflow and underflow if the final result is representable.)
<P>
Note that
<P><pre>
(multiple-value-bind (signif expon sign)
(decode-float <i>f</i>)
(scale-float signif expon))
== (abs <i>f</i>)
</pre><P>
and
<P><pre>
(multiple-value-bind (signif expon sign)
(decode-float <i>f</i>)
(* (scale-float signif expon) sign))
== <i>f</i>
</pre><P>
<P>
The function <tt>float-radix</tt> returns (as an integer)
the radix <i>b</i> of the floating-point argument.
<P>
The function <tt>float-sign</tt> returns a floating-point number <b><i>z</i></b> such
that <b><i>z</i></b> and <i>float1</i> have the same sign and also such that
<b><i>z</i></b> and <i>float2</i> have the same absolute value.
The argument <i>float2</i> defaults to the value of <tt>(float 1 <i>float1</i>)</tt>;
<tt>(float-sign x)</tt> therefore always produces a <tt>1.0</tt> or <tt>-1.0</tt>
of appropriate format
according to the sign of <tt>x</tt>. (Note that if an implementation
has distinct representations for negative zero and positive zero,
then <tt>(float-sign -0.0)</tt> => <tt>-1.0</tt>.)
<P>
The function <tt>float-digits</tt> returns, as a non-negative integer,
the number of radix-<i>b</i> digits
used in the representation of its argument (including any implicit
digits, such as a ``hidden bit'').
The function <tt>float-precision</tt>
returns, as a non-negative integer,
the number of significant radix-<i>b</i> digits present in the
argument; if the argument is (a floating-point)
zero, then the result is (an integer) zero.
For normalized floating-point numbers, the results of <tt>float-digits</tt>
and <tt>float-precision</tt>
will be the same, but the precision will be less than the
number of representation digits for a denormalized or zero number.
<P>
The function <tt>integer-decode-float</tt> is similar to <tt>decode-float</tt>
but for its first value returns,
as an <tt>integer</tt>, the significand scaled so as to be an integer.
For an argument <i>f</i>, this integer will be strictly less than
<P><pre>
<tt>(expt <i>b</i> (float-precision <i>f</i>))</tt>
</pre><P>
but no less than
<P><pre>
<tt>(expt <i>b</i> (- (float-precision <i>f</i>) 1))</tt>
</pre><P>
except that if <i>f</i> is zero, then the integer value will be zero.
<P>
The second value bears the same relationship to the first value
as for <tt>decode-float</tt>:
<P><pre>
(multiple-value-bind (signif expon sign)
(integer-decode-float <i>f</i>)
(scale-float (float signif <i>f</i>) expon))
== (abs <i>f</i>)
</pre><P>
<P>
The third value of <tt>integer-decode-float</tt> will be <tt>1</tt> or <tt>-1</tt>.
<P>
<hr>
<b>Rationale:</b> These functions allow the writing of machine-independent,
or at least machine-parameterized, floating-point software of reasonable
efficiency.
<hr>
<P>
<BR><b>[Function]</b><BR>
<tt>complex <i>realpart</i> &amp;optional <i>imagpart</i></tt><P>The arguments must be non-complex numbers; a number is returned
that has <i>realpart</i> as its real part and <i>imagpart</i> as its imaginary
part, possibly converted according to the rule of floating-point
contagion (thus both components will be of the same type).
If <i>imagpart</i> is not specified,
then <tt>(coerce 0 (type-of <i>realpart</i>))</tt> is
effectively used. Note that if both the <i>realpart</i> and <i>imagpart</i> are
rational and the <i>imagpart</i> is zero, then the result is just the
<i>realpart</i> because of the rule of canonical representation
for complex rationals. It follows that the result of <tt>complex</tt>
is not always a complex number; it may be simply a <tt>rational</tt>.
<P>
<BR><b>[Function]</b><BR>
<tt>realpart <i>number</i> <BR></tt><tt>imagpart <i>number</i></tt><P>These return the real and imaginary parts of a complex number. If
<i>number</i> is a non-complex number, then <tt>realpart</tt> returns its
argument <i>number</i> and <tt>imagpart</tt>
returns <tt>(* 0 <i>number</i>)</tt>, which
has the effect that the imaginary part of a rational is <tt>0</tt> and that of
a floating-point number is a floating-point zero of the same format.
<P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
A clever way to multiply a complex number <i>z</i> by <i>i</i> is to write
<P><pre>
(complex (- (imagpart <i>z</i>)) (realpart <i>z</i>))
</pre><P>
instead of <tt>(* <i>z</i> #c(0 1))</tt>. This cleverness is not always
gratuitous; it may be of particular importance in the presence of minus
zero. For example, if we are using IEEE standard floating-point arithmetic
and <b>z=4+0<i>i</i></b>, the result of the clever expression is <b>-0+4<i>i</i></b>, a true
<IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap41737.gif"> rotation of <b><i>z</i></b>, whereas the result of <tt>(* <i>z</i> #c(0 1))</tt>
is likely to be
<PRE>
(4+0<i>i</i>)(+0+<i>i</i>) = ((4)(+0)-(+0)(1))+((4)(1)+(+0)(+0)<i>i</i>
= ((+0)-(+0))+((4)+(+0))<i>i</i> = +0+4<i>i</i>
</PRE>
which could
land on the wrong side of a branch cut, for example.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR> <HR><A NAME=tex2html3151 HREF="node131.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3149 HREF="node121.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3143 HREF="node129.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3153 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3154 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3152 HREF="node131.html"> Logical Operations on </A>
<B>Up:</B> <A NAME=tex2html3150 HREF="node121.html"> Numbers</A>
<B> Previous:</B> <A NAME=tex2html3144 HREF="node129.html"> Branch CutsPrincipal </A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>