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.

Implementation note: 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.

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 j is assigned
a ``weight'' .
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 -1 minus the sum of the weights of the zero-bits, a negative integer.

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 logior, logand,
and logxor defined below then compute the union,
intersection, and symmetric difference operations on sets
represented in this way.

[Function]logior &rest integers

This returns the bit-wise logical inclusive or of its arguments.
If no argument is given, then the result is zero,
which is an identity for this operation.

[Function]logxor &rest integers

This returns the bit-wise logical exclusive or of its arguments.
If no argument is given, then the result is zero,
which is an identity for this operation.

[Function]logand &rest integers

This returns the bit-wise logical and of its arguments.
If no argument is given, then the result is -1,
which is an identity for this operation.

[Function]logeqv &rest integers

This returns the bit-wise logical equivalence (also known as exclusive nor)
of its arguments.
If no argument is given, then the result is -1,
which is an identity for this operation.

The function boole takes an operation op and two integers,
and returns an integer produced by performing the logical operation
specified by op 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 boole:

X3J13 voted in January 1989
(ARGUMENTS-UNDERSPECIFIED)
to clarify that the index must be a non-negative integer.

[Function]ash integercount

This function shifts integer arithmetically left by count bit
positions if count is positive,
or right by -count bit positions if count is negative.
The sign of the result is always the same as the sign of integer.

Mathematically speaking, this operation performs the computation
).

Logically, this moves all of the bits in integer 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:

(logbitp j (ash nk)) == (and (>= jk) (logbitp (- jk) n))

[Function]logcount integer

The number of bits in integer is determined and returned.
If integer is positive, the 1-bits in its binary
representation are counted. If integer is negative,
the 0-bits in its two's-complement binary representation are counted.
The result is always a non-negative integer.
For example:

This is useful in two different ways.
First, if integer is non-negative, then its value can be represented
in unsigned binary form in a field whose width in bits is
no smaller than (integer-length integer).
Second, regardless of the sign of integer, its value can be
represented in signed binary two's-complement form in a field
whose width in bits is no smaller than (+ (integer-length integer) 1).
For example: