Common Lisp the Language, 2nd Edition
![]()
Next: Random Numbers
Up: Numbers
Previous: Logical Operations
on
Several functions are provided for dealing with an arbitrary-width field of contiguous bits appearing anywhere in an integer. Such a contiguous set of bits is called a byte. Here the term byte does not imply some fixed number of bits (such as eight), rather a field of arbitrary and user-specifiable width.
The byte-manipulation functions use objects called byte
specifiers to designate a specific byte position within an integer.
The representation of a byte specifier is implementation-dependent; in
particular, it may or may not be a number. It is sufficient to know that
the function byte will construct one, and that the
byte-manipulation functions will accept them. The function
byte accepts two integers representing the
position and size of the byte and returns a byte
specifier. Such a specifier designates a byte whose width is
size and whose bits have weights
through
.
[Function]
bytesizeposition
byte takes two integers representing the size and
position of a byte and returns a byte specifier suitable for use as an
argument to byte-manipulation functions.
[Function]
byte-sizebytespec
byte-positionbytespec
Given a byte specifier, byte-size returns the size
specified as an integer; byte-position similarly returns
the position. For example:
(byte-size (byte j k)) == j
(byte-position (byte j k)) == k
[Function]
ldbbytespecinteger
bytespec specifies a byte of integer to be extracted. The result is returned as a non-negative integer. For example:
(logbitp j (ldb (byte s p) n)) == (and (< j s) (logbitp (+ j p) n))
The name of the function ldb means ``load byte.’’
Compatibility note: The MacLisp function
haipart can be implemented in terms of ldb as
follows:
(defun haipart (integer count)
(let ((x (abs integer)))
(if (minusp count)
(ldb (byte (- count) 0) x)
(ldb (byte count (max 0 (- (integer-length x) count)))
x))))
If the argument integer is specified by a form that is a
place form acceptable to setf, then
setf may be used with ldb to modify a byte
within the integer that is stored in that place. The effect is
to perform a dpb operation and then store the result back
into the place.
[Function]
ldb-testbytespecinteger
ldb-test is a predicate that is true if any of the bits
designated by the byte specifier bytespec are 1’s in
integer; that is, it is true if the designated field is
non-zero.
(ldb-test bytespec n) == (not (zerop (ldb bytespec n)))
[Function]
mask-fieldbytespecinteger
This is similar to ldb; however, the result contains the
specified byte of integer in the position specified by
bytespec, rather than in position 0 as with ldb.
The result therefore agrees with integer in the byte specified
but has zero-bits everywhere else. For example:
(ldb bs (mask-field bs n)) == (ldb bs n)
(logbitp j (mask-field (byte s p) n))
== (and (>= j p) (< j (+ p s)) (logbitp j n))
(mask-field bs n) == (logand n (dpb -1 bs 0))
If the argument integer is specified by a form that is a
place form acceptable to setf, then
setf may be used with mask-field to modify a
byte within the integer that is stored in that place. The
effect is to perform a deposit-field operation and then
store the result back into the place.
[Function]
dpbnewbytebytespecinteger
This returns a number that is the same as integer except in
the bits specified by bytespec. Let s be the size
specified by bytespec; then the low s bits of
newbyte appear in the result in the byte specified by
bytespec. The integer newbyte is therefore interpreted
as being right-justified, as if it were the result of ldb.
For example:
(logbitp j (dpb m (byte s p) n))
== (if (and (>= j p) (< j (+ p s)))
(logbitp (- j p) m)
(logbitp j n))
The name of the function dpb means ``deposit byte.’’
[Function]
deposit-fieldnewbytebytespecinteger
This function is to mask-field as dpb is to
ldb. The result is an integer that contains the bits of
newbyte within the byte specified by bytespec, and
elsewhere contains the bits of integer. For example:
(logbitp j (deposit-field m (byte s p) n))
== (if (and (>= j p) (< j (+ p s)))
(logbitp j m)
(logbitp j n))
Implementation note: If the bytespec is a
constant, one may of course construct, at compile time, an equivalent
mask m, for example by computing
(deposit-field -1bytespec0).
Given this mask m, one may then compute
(deposit-field newbyte bytespec integer)
by computing
(logior (logand newbyte m) (logand integer (lognot m)))
where the result of
(lognotm) can of course
also be computed at compile time. However, the following expression may
also be used and may require fewer temporary registers in some
situations:
(logxor integer (logand m (logxor integer newbyte)))
A related, though possibly less useful, trick is that
(let ((z (logand (logxor x y) m)))
(setq x (logxor z x))
(setq y (logxor z y)))
interchanges those bits of x and y for
which the mask m is 1, and leaves alone those
bits of x and y for which m is
0.
![]()
Next: Random Numbers
Up: Numbers
Previous: Logical Operations
on
AI.Repository@cs.cmu.edu