emacs.d/clones/lisp/www.cs.cmu.edu/Groups/AI/html/cltl/clm/node131.html

276 lines
14 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.7. Logical Operations on Numbers</TITLE>
</HEAD>
<BODY>
<meta name="description" value=" Logical Operations 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=tex2html3163 HREF="node132.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3161 HREF="node121.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3155 HREF="node130.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3165 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3166 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3164 HREF="node132.html"> Byte Manipulation Functions</A>
<B>Up:</B> <A NAME=tex2html3162 HREF="node121.html"> Numbers</A>
<B> Previous:</B> <A NAME=tex2html3156 HREF="node130.html"> Type Conversions and </A>
<HR> <P>
<H1><A NAME=SECTION001670000000000000000>12.7. Logical Operations on Numbers</A></H1>
<P>
The logical operations in this section require integers
as arguments; it is an error to supply a non-integer as an argument.
The functions all treat integers as if
they were represented in two's-complement notation.
<P>
<hr>
<b>Implementation note:</b> Internally, of course, an implementation of
Common Lisp may or may not use a two's-complement representation.
All that is necessary is that the logical operations
perform calculations so as to give this appearance to the user.
<hr>
<P>
The logical operations provide a convenient way to represent
an infinite vector of bits. Let such a conceptual vector be
indexed by the non-negative integers. Then bit <b><i>j</i></b> is assigned
a ``weight'' <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap41801.gif">.
Assume that only a finite number of bits are 1's
or only a finite number of bits are 0's.
A vector with only a finite number of one-bits is represented
as the sum of the weights of the one-bits, a positive integer.
A vector with only a finite number of zero-bits is represented
as <tt>-1</tt> minus the sum of the weights of the zero-bits, a negative integer.
<P>
This method of using integers to represent bit-vectors can in turn
be used to represent sets. Suppose that some (possibly countably
infinite) universe of discourse
for sets is mapped into the non-negative integers.
Then a set can be represented as a bit vector; an element is in the
set if the bit whose index corresponds to that element is a one-bit.
In this way all finite sets can be represented (by positive
integers), as well as all sets whose complements are finite
(by negative integers). The functions <tt>logior</tt>, <tt>logand</tt>,
and <tt>logxor</tt> defined below then compute the union,
intersection, and symmetric difference operations on sets
represented in this way.
<P>
<BR><b>[Function]</b><BR>
<tt>logior &amp;rest <i>integers</i></tt><P>This returns the bit-wise logical <i>inclusive or</i> of its arguments.
If no argument is given, then the result is zero,
which is an identity for this operation.
<P>
<BR><b>[Function]</b><BR>
<tt>logxor &amp;rest <i>integers</i></tt><P>This returns the bit-wise logical <i>exclusive or</i> of its arguments.
If no argument is given, then the result is zero,
which is an identity for this operation.
<P>
<BR><b>[Function]</b><BR>
<tt>logand &amp;rest <i>integers</i></tt><P>This returns the bit-wise logical <i>and</i> of its arguments.
If no argument is given, then the result is <tt>-1</tt>,
which is an identity for this operation.
<P>
<BR><b>[Function]</b><BR>
<tt>logeqv &amp;rest <i>integers</i></tt><P>This returns the bit-wise logical <i>equivalence</i> (also known as <i>exclusive nor</i>)
of its arguments.
If no argument is given, then the result is <tt>-1</tt>,
which is an identity for this operation.
<P>
<BR><b>[Function]</b><BR>
<tt>lognand <i>integer1</i> <i>integer2</i> <BR></tt><tt>lognor <i>integer1</i> <i>integer2</i> <BR></tt><tt>logandc1 <i>integer1</i> <i>integer2</i> <BR></tt><tt>logandc2 <i>integer1</i> <i>integer2</i> <BR></tt><tt>logorc1 <i>integer1</i> <i>integer2</i> <BR></tt><tt>logorc2 <i>integer1</i> <i>integer2</i></tt><P>These are the other six non-trivial bit-wise logical operations
on two arguments. Because they are not associative,
they take exactly two arguments rather than any non-negative number
of arguments.
<P><pre>
(lognand <i>n1</i> <i>n2</i>) == (lognot (logand <i>n1</i> <i>n2</i>))
(lognor <i>n1</i> <i>n2</i>) == (lognot (logior <i>n1</i> <i>n2</i>))
(logandc1 <i>n1</i> <i>n2</i>) == (logand (lognot <i>n1</i>) <i>n2</i>)
(logandc2 <i>n1</i> <i>n2</i>) == (logand <i>n1</i> (lognot <i>n2</i>))
(logorc1 <i>n1</i> <i>n2</i>) == (logior (lognot <i>n1</i>) <i>n2</i>)
(logorc2 <i>n1</i> <i>n2</i>) == (logior <i>n1</i> (lognot <i>n2</i>))
</pre><P>
<P>
The ten bit-wise logical operations on two integers are summarized
in the following table:
<pre>
----------------------------------------------------------------
<i>integer1</i> 0 0 1 1
<i>integer2</i> 0 1 0 1 Operation Name
----------------------------------------------------------------
logand 0 0 0 1 and
logior 0 1 1 1 inclusive or
logxor 0 1 1 0 exclusive or
logeqv 1 0 0 1 equivalence (exclusive nor)
lognand 1 1 1 0 not-and
lognor 1 0 0 0 not-or
logandc1 0 1 0 0 and complement of <i>integer1</i> with <i>integer2</i>
logandc2 0 0 1 0 and <i>integer1</i> with complement of <i>integer2</i>
logorc1 1 1 0 1 or complement of <i>integer1</i> with <i>integer2</i>
logorc2 1 0 1 1 or <i>integer1</i> with complement of <i>integer2</i>
</pre>
<p>
<BR><b>[Function]</b><BR>
<tt>boole <i>op</i> <i>integer1</i> <i>integer2</i> <BR>
<BR><b>[Constant]</b><BR>
</tt><tt>boole-clr <BR>
</tt><tt>boole-set <BR>
</tt><tt>boole-1 <BR>
</tt><tt>boole-2 <BR>
</tt><tt>boole-c1 <BR>
</tt><tt>boole-c2 <BR>
</tt><tt>boole-and <BR>
</tt><tt>boole-ior <BR>
</tt><tt>boole-xor <BR>
</tt><tt>boole-eqv <BR>
</tt><tt>boole-nand <BR>
</tt><tt>boole-nor <BR>
</tt><tt>boole-andc1 <BR>
</tt><tt>boole-andc2 <BR>
</tt><tt>boole-orc1 <BR>
</tt><tt>boole-orc2</tt><P>The function <tt>boole</tt> takes an operation <i>op</i> and two integers,
and returns an integer produced by performing the logical operation
specified by <i>op</i> on the two integers. The precise values of
the sixteen constants are implementation-dependent, but they are
suitable for use as the first argument to <tt>boole</tt>:
<P>
<pre>
----------------------------------------------------------------
<i>integer1</i> 0 0 1 1
<i>integer2</i> 0 1 0 1 Operation Performed
----------------------------------------------------------------
boole-clr 0 0 0 0 always 0
boole-set 1 1 1 1 always 1
boole-1 0 0 1 1 <i>integer1</i>
boole-2 0 1 0 1 <i>integer2</i>
boole-c1 1 1 0 0 complement of <i>integer1</i>
boole-c2 1 0 1 0 complement of <i>integer2</i>
boole-and 0 0 0 1 and
boole-ior 0 1 1 1 inclusive or
boole-xor 0 1 1 0 exclusive or
boole-eqv 1 0 0 1 equivalence (exclusive nor)
boole-nand 1 1 1 0 not-and
boole-nor 1 0 0 0 not-or
boole-andc1 0 1 0 0 and complement of <i>integer1</i> with <i>integer2</i>
boole-andc2 0 0 1 0 and <i>integer1</i> with complement of <i>integer2</i>
boole-orc1 1 1 0 1 or complement of <i>integer1</i> with <i>integer2</i>
boole-orc2 1 0 1 1 or <i>integer1</i> with complement of <i>integer2</i>
</pre>
<p>
<tt>boole</tt> can therefore compute all sixteen logical functions on two
arguments. In general,
<P><pre>
(boole boole-and x y) == (logand x y)
</pre><P>
and the latter is more perspicuous. However, <tt>boole</tt> is useful when it
is necessary to parameterize a procedure so that it can use
one of several logical operations.
<P>
<BR><b>[Function]</b><BR>
<tt>lognot <i>integer</i></tt><P>This returns the bit-wise logical <i>not</i> of its argument.
Every bit of the result is the complement of the corresponding bit
in the argument.
<P><pre>
(logbitp <i>j</i> (lognot <i>x</i>)) == (not (logbitp <i>j</i> <i>x</i>))
</pre><P>
<P>
<BR><b>[Function]</b><BR>
<tt>logtest <i>integer1</i> <i>integer2</i></tt><P><tt>logtest</tt> is a predicate that is true if any of
the bits designated by the 1's in <i>integer1</i> are 1's in <i>integer2</i>.
<P><pre>
(logtest <i>x</i> <i>y</i>) == (not (zerop (logand <i>x</i> <i>y</i>)))
</pre><P>
<P>
<BR><b>[Function]</b><BR>
<tt>logbitp <i>index</i> <i>integer</i></tt><P><tt>logbitp</tt> is true if the bit in <i>integer</i> whose index
is <i>index</i> (that is, its weight is <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap41803.gif">) is a one-bit;
otherwise it is false.
For example:
<P><pre>
(logbitp 2 6) is true
(logbitp 0 6) is false
(logbitp <i>k</i> <i>n</i>) == (ldb-test (byte 1 <i>k</i>) <i>n</i>)
</pre><P>
<img align=bottom alt="change_begin" src="gif/change_begin.gif"><br>
X3J13 voted in January 1989
(ARGUMENTS-UNDERSPECIFIED) <A NAME=13426>&#160;</A>
to clarify that the <i>index</i> must be a non-negative integer.
<br><img align=bottom alt="change_end" src="gif/change_end.gif">
<P>
<BR><b>[Function]</b><BR>
<tt>ash <i>integer</i> <i>count</i></tt><P>This function shifts <i>integer</i> arithmetically left by <i>count</i> bit
positions if <i>count</i> is positive,
or right by <b>-<i>count</i></b> bit positions if <i>count</i> is negative.
The sign of the result is always the same as the sign of <i>integer</i>.
<P>
Mathematically speaking, this operation performs the computation
<IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap41807.gif">).
<P>
Logically, this moves all of the bits in <i>integer</i> to the left,
adding zero-bits at the bottom, or moves them to the right,
discarding bits. (In this context the question of what gets shifted
in on the left is irrelevant; integers, viewed as strings of bits,
are ``half-infinite,'' that is, conceptually extend infinitely far to the left.)
For example:
<P><pre>
(logbitp <i>j</i> (ash <i>n</i> <i>k</i>)) == (and (&gt;= <i>j</i> <i>k</i>) (logbitp (- <i>j</i> <i>k</i>) <i>n</i>))
</pre><P>
<P>
<BR><b>[Function]</b><BR>
<tt>logcount <i>integer</i></tt><P>The number of bits in <i>integer</i> is determined and returned.
If <i>integer</i> is positive, the <tt>1</tt>-bits in its binary
representation are counted. If <i>integer</i> is negative,
the <tt>0</tt>-bits in its two's-complement binary representation are counted.
The result is always a non-negative integer.
For example:
<P><pre>
(logcount 13) => 3 ;Binary representation is ...0001101
(logcount -13) => 2 ;Binary representation is ...1110011
(logcount 30) => 4 ;Binary representation is ...0011110
(logcount -30) => 4 ;Binary representation is ...1100010
</pre><P>
The following identity always holds:
<P><pre>
(logcount x) == (logcount (- (+ x 1)))
== (logcount (lognot x))
</pre><P>
<P>
<BR><b>[Function]</b><BR>
<tt>integer-length <i>integer</i></tt><P>This function performs the computation
<PRE><TT> <IMG ALIGN=BOTTOM ALT="" SRC="_24769_tex2html_wrap41797.gif">
</TT></PRE>
This is useful in two different ways.
First, if <i>integer</i> is non-negative, then its value can be represented
in unsigned binary form in a field whose width in bits is
no smaller than <tt>(integer-length <i>integer</i>)</tt>.
Second, regardless of the sign of <i>integer</i>, its value can be
represented in signed binary two's-complement form in a field
whose width in bits is no smaller than <tt>(+ (integer-length <i>integer</i>) 1)</tt>.
For example:
<P><pre>
(integer-length 0) => 0
(integer-length 1) => 1
(integer-length 3) => 2
(integer-length 4) => 3
(integer-length 7) => 3
(integer-length -1) => 0
(integer-length -4) => 2
(integer-length -7) => 3
(integer-length -8) => 3
</pre><P>
<P>
<hr>
<b>Compatibility note:</b> This function is similar to the MacLisp
function <tt>haulong</tt>. One may define <tt>haulong</tt> as
<P><pre>
(haulong x) == (integer-length (abs x))
</pre><P>
<hr>
<P>
<BR> <HR><A NAME=tex2html3163 HREF="node132.html"><IMG ALIGN=BOTTOM ALT="next" SRC="icons/next_motif.gif"></A> <A NAME=tex2html3161 HREF="node121.html"><IMG ALIGN=BOTTOM ALT="up" SRC="icons/up_motif.gif"></A> <A NAME=tex2html3155 HREF="node130.html"><IMG ALIGN=BOTTOM ALT="previous" SRC="icons/previous_motif.gif"></A> <A NAME=tex2html3165 HREF="node1.html"><IMG ALIGN=BOTTOM ALT="contents" SRC="icons/contents_motif.gif"></A> <A NAME=tex2html3166 HREF="index.html"><IMG ALIGN=BOTTOM ALT="index" SRC="icons/index_motif.gif"></A> <BR>
<B> Next:</B> <A NAME=tex2html3164 HREF="node132.html"> Byte Manipulation Functions</A>
<B>Up:</B> <A NAME=tex2html3162 HREF="node121.html"> Numbers</A>
<B> Previous:</B> <A NAME=tex2html3156 HREF="node130.html"> Type Conversions and </A>
<HR> <P>
<HR>
<P><ADDRESS>
AI.Repository@cs.cmu.edu
</ADDRESS>
</BODY>