patternMinor
Invert the bits of a non-negative integer in Common Lisp (SBCL)
Viewed 0 times
invertthelispnonbitscommonsbclnegativeinteger
Problem
I'm doing code challenges to learn Common Lisp. I'm trying to invert all the bits in any given positive integer.
My current solution does it the math way, by recursing on a number, dividing it by two, and inverting the remainder before multiplying and adding back up:
Is there a simpler way to do this using built-in functions?
My current solution does it the math way, by recursing on a number, dividing it by two, and inverting the remainder before multiplying and adding back up:
(defun invert-bits (n)
(if (> n 0)
(+ (* (invert-bits (truncate (/ n 2))) 2)
(if (= (rem n 2) 1) 0 1))
0))
Is there a simpler way to do this using built-in functions?
Solution
A possible way is to use one of the bitwise logical operators on integers, that treat integers as binary numbers. For instance, by using the
The function
logxor operator, we could write:(defun invert-bits2 (n)
(if (> n 0)
(logxor (1- (expt 2 (integer-length n))) n)
0))The function
integer-length returns the number of bits of the binary representation of an integer, so that (1- (expt 2 (integer-length n))) is a binary number with all ones and the same length as n.CL-USER> (loop for f in '(identity invert-bits invert-bits2)
do (format t "~20b~%" (funcall f 300212)))
1001001010010110100
110110101101001011
110110101101001011
NILCode Snippets
(defun invert-bits2 (n)
(if (> n 0)
(logxor (1- (expt 2 (integer-length n))) n)
0))CL-USER> (loop for f in '(identity invert-bits invert-bits2)
do (format t "~20b~%" (funcall f 300212)))
1001001010010110100
110110101101001011
110110101101001011
NILContext
StackExchange Code Review Q#152239, answer score: 5
Revisions (0)
No revisions yet.