Formatting integers in different radixes

format has four directives for formatting integers with different radixes:

  • ~B¬†formats as binary: (format nil "~B" 42) => "101010"
  • ~O formats as octal: (format nil "~O" 42) => "52"
  • ~X formats as hexadecimal: (format nil "~X" 666) => "29A"
  • ~R formats with an arbitrary radix between 2 and 36: (format nil "~36R" 18321) => "E4X"

Each directive takes padding and pad-character options (as well as other options). I define these functions in my init files to quickly dump out hex and bit views of integers:

(defun :hex (value &optional (size 4))
  (format t "~v,'0X" size value))

(defun :bits (value &optional (size 8))
  (format t "~v,'0B" size value))
  
* (:bits 42)
00101010

* (:hex 666)
029A

The lower-level write function accepts a :base argument that specifies a radix to use when printing integers. The default value is taken from *print-base*. For example, (write-to-string 65535 :base 16) => "FFFF". Since write underlies how other standard functions produce output, binding *print-base* will affect pretty much everything.