HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Invert the bits of a non-negative integer in Common Lisp (SBCL)

Submitted by: @import:stackexchange-codereview··
0
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:

(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 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
NIL

Code 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
NIL

Context

StackExchange Code Review Q#152239, answer score: 5

Revisions (0)

No revisions yet.