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