Java がBigIntegerクラスで行うことと互換性のある方法で Integers を読み書きする必要があります。
この BigInteger の 2 の補数表現を含むバイト配列を返します。バイト配列はビッグ エンディアンのバイト順になります。最上位バイトは 0 番目の要素にあります。配列には、少なくとも 1 つの符号ビット (ceil((this.bitLength() + 1)/8)) を含む、この BigInteger を表すために必要な最小バイト数が含まれます。
悲しいことに、これは提供するものを除外しData.Binary
ます. ライブラリのどこかに、この規則に従ってByteString
<->変換を行うのに効率的なものはありますか? Integer
そうでない場合、どうすればそれを行うことができますか?
Thomas M. DuBuisson からの回答 (および次の議論) に基づいて、現在私は持っています
i2bs :: Integer -> B.ByteString
i2bs x
| x == 0 = B.singleton 0
| x < 0 = i2bs $ 2 ^ (8 * bytes) + x
| otherwise = B.reverse $ B.unfoldr go x
where
bytes = (integerLogBase 2 (abs x) + 1) `quot` 8 + 1
go i = if i == 0 then Nothing
else Just (fromIntegral i, i `shiftR` 8)
integerLogBase :: Integer -> Integer -> Int
integerLogBase b i =
if i < b then
0
else
-- Try squaring the base first to cut down the number of divisions.
let l = 2 * integerLogBase (b*b) i
doDiv :: Integer -> Int -> Int
doDiv i l = if i < b then l else doDiv (i `div` b) (l+1)
in doDiv (i `div` (b^l)) l
これは私が望んでいたものよりも冗長ですが、まだbs2i
関数を見逃しています。