0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Clojureでバイト配列を整数に変換する

Posted at

Clojureでバイト配列を整数に変換する方法のメモ。

以下のコードでバイト配列を符号あり/なしのlong値に変換できます。
※ビッグエンディアンでの変換

sample.clj
(def << bit-shift-left)
(def >> bit-shift-right)

(defn unsigned [^bytes bytea]
  {:pre [(<= 1 (alength bytea) 7)]}
  (areduce bytea i ret 0
           (bit-or (<< ret 8) (bit-and 0xff (aget bytea i)))))

(defn signed [^bytes bytea]
  {:pre [(<= 1 (alength bytea) 8)]}
  (areduce bytea i ret (if (neg? (aget bytea 0)) -1 0)
           (bit-or (<< ret 8) (bit-and 0xff (aget bytea i)))))

areduceを使うと、配列に対してJavaのforループと似たような処理ができます。
areduceの引数のiretはインデックスと戻り値の名前で、名前は自由に決められます。

リトルエンディアンのバイト配列の場合、配列に対するreverseを先にしておきます。

sample2.clj
(defn areverse-byte [^bytes bytea]
  (let [len (alength bytea)]
    (areduce bytea i ret (byte-array len)
             (do (aset-byte ret (- len i 1) (aget bytea i)) ret))))

整数からバイト配列への変換は以下のコードでできます。

sample3.clj
(defn ^bytes ->bytes [^long len ^long value]
  {:pre [(<= 1 len 8)]}
  (byte-array
   (reduce (fn [a i] (conj a (>> value (* (- len i 1) 8)))) [] (range len))))

なお、バイト数が8固定で符号ありlongへの変換のみなら
(.. (java.nio.ByteBuffer/wrap bytea) asLongBuffer get)
の方が4倍くらい性能はいいです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?