Ich brauche ganzen Zahlen in einer Art und Weise zu lesen und zu schreiben, die mit kompatibel ist, was Java tut mit seiner BigInteger Klasse:Read/Write Haskell Integer in Zweierkomplement-Darstellung
ein Byte-Array Gibt die Zweierkomplement-Darstellung enthält von dieser BigInteger. Das Byte-Array befindet sich in Big-Endian-Byte-Reihenfolge: Das höchstwertige Byte befindet sich im nullten Element. Das Array enthält die minimale Anzahl von Bytes, die benötigt werden, um diesen BigInteger darzustellen, einschließlich mindestens ein Vorzeichen-Bit, das ist (ceil ((this.bitLength() + 1)/8)).
Leider schließt dies aus, was Data.Binary
bietet. Gibt es etwas Effizientes, um eine ByteString
< ->Integer
Konvertierung nach dieser Konvention irgendwo in den Bibliotheken zu tun? Wenn nicht, wie kann es gemacht werden?
Basierend auf der Antwort von Thomas M. Dubuisson (und der folgenden Diskussion) Ich habe derzeit
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
Welche als ausführlicher ist, was ich gehofft, noch fehlt die bs2i
Funktion.
Muss es tragbar sein, oder können Sie GHC mit dem 'integer-gmp' Paket annehmen? –
Ich würde eine tragbare Lösung bevorzugen. Wenn ich mich richtig erinnere, kann sogar GHC ohne GMP gebaut werden? Das wäre dann etwas zu zerbrechlich. – Waldheinz
Ja, es kann mit "ganzzahlig-einfach" gebaut werden. Sie könnten nur effizienter sein, wenn Sie die Interna verwenden. Eine weitere Frage, wollen Sie einen 'ByteString', der nur die Bits der Zahl enthält, oder soll er Teil eines größeren' ByteString' sein, so dass Sie ein Feld haben, das angibt, wie viele Bytes die Repräsentation ausmacht? –