On 12 March 2010 23:26, Scott <sbuck...@gmail.com> wrote:
> How do I write a function 'bit' that converts an integer to binary
> representation:
>
> (bit 0) -> 2r0
> (bit 1) -> 2r1
> (bit 2) -> 2r10
> (bit 3) -> 2r11

I understand that you want a way to obtain a string representation of
a number in binary. I think you need to dispatch on class:

(Integer/toBinaryString (int 5)) ; => "101"
(Integer/toBinaryString (Integer. 5)) => "101"
(Long/toBinaryString (long 5)) ; => "101"
(Long/toBinaryString (Long. (long 5))) ; => "101"

(.toString (bigint 5) 2) ; the "2" indicates the radix; => "101"
(.toString (BigInteger. "5") 2) ; => "101"

As far as I can tell, you can't use the int/long method with bigints
or the other way around.

If you'd like to add the "2r" in front, just use str:

(str "2r" "101") ; => "2r101"

> As well, as function 'bit-concat' with the following behavior:
>
> (bit-concat 2r1 2r00) -> 2r100
> (bit-concat 2r0 2r00) -> 2r000
> (bit-concat 2r011 2r1100) -> 2r0111100

I'd prefer to have bit-concat operate on actual numbers, not on
strings; you can convert the result later. To that end, here's a
possible solution (I'm *sure* there must be a better way... but it
works):

(let [ls (zipmap (map #(loop [n % r 1]
                         (if (zero? n)
                           r
                           (recur (dec n) (* 2 r))))
                      (range 0 128))
                 (map inc (range 0 128)))]
  (defn bit-length [n]
    (if (zero? n)
      0
      (condp = (class n)
        Integer    (ls (Integer/highestOneBit n))
        Long       (ls (Long/highestOneBit n))
        BigInteger (.bitLength n)))))

(comment
  ; this returns true
  (every? #(== (bit-length %) (.bitLength %))
          (map bigint (range 0 1000))))

(defn bit-concat [n m]
  (bit-or (bit-shift-left n (bit-length m))
          m))

This will work as expected unless you use unboxed ints:

user> (bit-shift-left (int 1) 63)
-2147483648
user> (bit-shift-left (Integer. 1) 63)
9223372036854775808
user> (bit-shift-left (long 1) 128)
340282366920938463463374607431768211456
user> (bit-shift-left (long 1) 200)
1606938044258990275541962092341162602522202993782792835301376
user> (class (bit-shift-left (long 1) 200))
java.math.BigInteger

Sincerely,
Michał

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to