I would like to (modulo) increment a particular bit of a bit-array. How do you do that in Common Lisp ?
For example, I want to increment the value of bit 3 in bit-array #*0001 (The bit 3 has the value 1). I want to modulo-increment it by 1, so that it would turn to 0.
CL-USER> (setf x #*0001)
#*0001
CL-USER> (bit x 3)
1 (1 bit, #x1, #o1, #b1)
CL-USER> (setf (bit x 3) (+ (bit x 3) 1))
TYPE-ERROR :
The value
2
is not of type
BIT
when setting an element of (ARRAY BIT)
[Condition of type TYPE-ERROR]
Of course, I have the same error when using INCF instead of SETF. I want a modulo-increment, that is I don't want #*0001 to turn to #*0010 but to be #*0000.
I have an error when using NOT in :
CL-USER> (setf (bit x 3) (not (bit x 3)))
Value of #:NEW1 in ((SETF AREF) #:NEW1 #:G0 3) is NIL, not a BIT.
[Condition of type SIMPLE-TYPE-ERROR]
All the same, when using LOGNOT:
CL-USER> (setf (bit x 3) (lognot (bit x 3)))
Value of (LOGNOT (BIT X 3)) in
((SETF AREF) #:NEW1 #:G0 3)
is
-2,
not a
BIT.
[Condition of type SIMPLE-TYPE-ERROR]
I don't see how I could use BIT-NOT as it wants 2 bit-arrays as input. I just want to invert (modulo-increment) a bit in a bit-array from its position in the bit array.
The "literal" way to do this would be something like
(defvar *array* (make-array 4 :element-type 'bit :initial-element 0))
(setf (bit *array* 2) (mod (1+ (bit *array* 2)) 2))
(print *array*) ;; ==> #*0010
(setf (bit *array* 2) (mod (1+ (bit *array* 2)) 2))
(print *array*) ;; ==> #*0000
or as self-contained function:
(defun nbit-flip (bitset index)
(setf (bit bitset index) (mod (1+ (bit bitset index)) 2))
bitset)
You could use (logxor 1 ...)
to do the flipping like
(defun nbit-flip (bitset index)
(setf (bit bitset index) (logxor 1 (bit bitset index)))
bitset)
Just stick to that which signals your intention most clearly.