我需要以与 Java 对其BigInteger类所做的兼容的方式读取和写入整数:
返回包含此 BigInteger 的二进制补码表示的字节数组。字节数组将采用大端字节序:最高有效字节位于第零个元素中。该数组将包含表示此 BigInteger 所需的最小字节数,包括至少一个符号位,即 (ceil((this.bitLength() + 1)/8))。
可悲的是,这排除了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
功能。