Novices sometimes ask how to get a convert an integer to a list of bits, often for the purpose of iterating over the bits somehow. Common Lisp has a rich set of functions for directly accessing the bits of an integer, so constructing an intermediate list of bits is rarely necessary.

Here are a few examples of accessing the bits of an integer.

With integer-length and logbitp to test the bit at a particular index:

(defun list-of-bits (integer) (loop for index below (integer-length integer) collect (if (logbitp index integer) 1 0)))

With ash to shift the integer to the right and logand to test the least-significant bit:

(defun list-of-bits (integer) (loop repeat (integer-length integer) for i = integer then (ash i -1) collect (logand i 1)))

With ash to shift a one-bit mask to the left and logtest to test the mask bit against the integer:

(defun list-of-bits (integer) (loop repeat (integer-length integer) for mask = 1 then (ash mask 1) collect (if (logtest mask integer) 1 0)))

With byte to construct a byte specifier and ldb to extract a field from the integer:

(defun list-of-bits (integer) (loop for position below (integer-length integer) collect (ldb (byte 1 position) integer)))

update Unfortunately, all these examples are buggy - they collect bits in the wrong order. I used loop/collect to avoid having to reverse the results, but didn’t think it through properly. Here are some updated definitions with dotimes that give the results in the intended order:

(defun list-of-bits (integer) (let ((bits '())) (dotimes (index (integer-length integer) bits) (push (if (logbitp index integer) 1 0) bits))))

(defun list-of-bits (integer) (let ((i integer) (bits '())) (dotimes (j (integer-length integer) bits) (push (logand i 1) bits) (setf i (ash i -1)))))

(defun list-of-bits (integer) (let ((mask 1) (bits '())) (dotimes (i (integer-length integer) bits) (push (if (logtest mask integer) 1 0) bits) (setf mask (ash mask 1)))))

(defun list-of-bits (integer) (let ((bits '())) (dotimes (position (integer-length integer) bits) (push (ldb (byte 1 position) integer) bits))))