gpt4 book ai didi

haskell - 以二进制补码表示形式读取/写入 Haskell 整数

转载 作者:行者123 更新时间:2023-12-04 18:10:39 26 4
gpt4 key购买 nike

我需要以一种与 Java 使用它的 BigInteger 兼容的方式读写整数类(class):

Returns a byte array containing the two's-complement representation of this BigInteger. The byte array will be in big-endian byte-order: the most significant byte is in the zeroth element. The array will contain the minimum number of bytes required to represent this BigInteger, including at least one sign bit, which is (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功能。

最佳答案

偷走i2bsbs2i来自crypto-api的例程并对其进行轻微修改:

import Data.ByteString as B

-- |@i2bs bitLen i@ converts @i@ to a 'ByteString'
i2bs :: Integer -> B.ByteString
i2bs = B.reverse . B.unfoldr (\i' -> if i' == 0 then Nothing
else Just (fromIntegral i', i' `shiftR` 8))


-- |@bs2i bs@ converts the 'ByteString' @bs@ to an 'Integer' (inverse of 'i2bs')
bs2i :: B.ByteString -> Integer
bs2i = B.foldl' (\i b -> (i `shiftL` 8) + fromIntegral b) 0 . B.reverse

您可以通过首先确定位大小并使用原始 i2bs 来稍微提高效率。按顺序构造字节串(为您节省反向成本)。

(编辑:我应该注意这没有使用 Java 解析器进行测试,但是这个基本结构应该很容易让你改变以考虑任何丢失的位)。

关于haskell - 以二进制补码表示形式读取/写入 Haskell 整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15047191/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com