Skip to main content

logtest

logtest Function

Syntax:

logtest integer-1 integer-2 → generalized-boolean

Arguments and Values:

integer-1—an integer .

integer-2—an integer .

generalized-boolean—a generalized boolean.

Description:

Returns true if any of the bits designated by the 1’s in integer-1 is 1 in integer-2; otherwise it is false. integer-1 and integer-2 are treated as if they were binary.

Negative integer-1 and integer-2 are treated as if they were represented in two’s-complement binary.

Examples:

(logtest 1 7) → true 
(logtest 1 2) → false

(logtest -2 -1) → true
(logtest 0 -1) → false

Exceptional Situations:

Should signal an error of type type-error if integer-1 is not an integer . Should signal an error of type type-error if integer-2 is not an integer .

Notes:

(logtest x y) (not (zerop (logand x y)))

Expanded Reference: logtest

Testing if any bits overlap

logtest returns true if any bit that is 1 in the first integer is also 1 in the second integer. It is equivalent to (not (zerop (logand x y))).

(logtest 1 7)
=> T
(logtest 1 2)
=> NIL
(logtest 6 3)
=> T
(logtest 0 -1)
=> NIL

Testing with negative integers

Negative integers in two's-complement have infinite leading 1-bits, so they always share bits with other negative integers.

(logtest -2 -1)
=> T
(logtest -1 -1)
=> T

Practical use: checking bit flags

logtest is a concise way to check if any flags in a mask are set.

(defconstant +flag-a+ #b001)
(defconstant +flag-b+ #b010)
(defconstant +flag-c+ #b100)

(let ((active-flags (logior +flag-a+ +flag-c+))) ; #b101
(list (logtest +flag-a+ active-flags) ; flag A set?
(logtest +flag-b+ active-flags) ; flag B set?
(logtest +flag-c+ active-flags) ; flag C set?
(logtest (logior +flag-a+ +flag-b+) ; either A or B set?
active-flags)))
=> (T NIL T T)

Equivalence to logand

logtest is defined as checking whether the bitwise AND is non-zero.

(eql (logtest 12 10) (not (zerop (logand 12 10))))
=> T
(eql (logtest 8 7) (not (zerop (logand 8 7))))
=> T