Of the two functions included here, which is the more idiomatic of the two? Do neither represent something that could be considered good Clojure? Is there a much more elegant way of accomplishing this? Looking for some constructive criticisms on style / direction.
(on github: https://github.com/jtrim/clojure-sandbox/blob/master/bit-sandbox/src/bit_sandbox/core.clj#L25)
Both versions of this function take a vector of number-represented bytes and turns the bytes into a number. e.g.
(bytes-to-num [0 0 0 0]) ;=> number `0`
(bytes-to-num [0 0 0 255]) ;=> number `255`
(bytes-to-num [0 0 1 0]) ;=> number `256`
; etc...
At each level of recursion, the byte in question is shifted left a number corresponding to the number of bytes at that given level of recursion, then added to the running sum and either returned or passed down another level.
(defn bytes-to-num-v1 [vec-bytes]
(loop [sum 0, the-bytes vec-bytes]
(if (empty? the-bytes)
sum
(recur
(+ sum (shifted-byte (first the-bytes) (count (rest the-bytes))))
(rest the-bytes)))))
v2 reduces the vector of bytes with an accumulator of [sum position] where:
:
(defn bytes-to-num-v2 [vec-bytes]
(first (reduce
(fn [acc, the-byte]
[(+ (first acc) (shifted-byte the-byte (last acc))) (dec (last acc))])
[0 (dec (count vec-bytes))]
vec-bytes)))
Source of the shifted-byte function for completeness:
(defn shifted-byte [num-byte-value, shift-by]
(bit-shift-left
(bit-and num-byte-value 0xFF)
(* shift-by 8)))
You're trying to convert the bytes into an unsigned big integer, right?
In which case you probably want something like:
(defn bytes-to-num [bytes]
(reduce (fn [acc x] (+ x (* 256 acc))) bytes))
General comments:
Alternatively you can use the Java interop to directly use the BigInteger constructor that accepts a byte array. The only trickiness here is that Java expects signed bytes, so you need to do a little conversion first:
(defn to-signed-byte [x] (.byteValue x))
(BigInteger. (byte-array (map to-signed-byte [ 0 0 0 255])))
=> 255
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With