I need to get all 32 bits of an Integer in Clojure into String format.
Current: (Integer/toBinaryString 10) -> "1010"
Desired: (Integer/toBinaryString 10) -> "0000000000001010"
How can I do this easily and efficiently?
For unsigned integers, you could use clojure.pprint/cl-format directly. This example formats n as a binary string of at least 32 characters, left padded with 0 characters:
(require '[clojure.pprint :as pp])
(defn unsigned-binary-32 [n]
(pp/cl-format nil "~32,'0B" n))
For signed integers there is a little more required:
(defn signed-binary-32 [n]
(unsigned-binary-32 (bit-and n 0xffffffff)))
@leetwinski makes an excellent point! Here is an even easier version (for positive numbers only!):
(defn int->binary-str-32
[arg]
(str/pad-left
(Long/toBinaryString arg) ; convert int to string
32 ; pad width
\0 ; pad char
))
(int->binary-str-32 12345) => "00000000000000000011000000111001"
Original Answer
The Tupelo Library has a function you can use. Here is an example using my favorite template project:
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[clojure.string :as str]
[tupelo.bits :as bits ]
))
(defn int->binary-str-32
[arg]
(str/join
(mapv bits/bit->char
(take-last 32
(bits/long->bits-unsigned arg)))))
with result:
(int->binary-str-32 5) => "00000000000000000000000000000101"
(int->binary-str-32 Short/MAX_VALUE) => "00000000000000000111111111111111"
(int->binary-str-32 Integer/MAX_VALUE) => "01111111111111111111111111111111"
This only works on non-negative values (negative values are left as an exercise for the reader).
Or you can modify the original source code.