fix: use 2s complement signed bigint

This commit is contained in:
orion 2023-12-21 13:13:44 -06:00
parent 4904879515
commit 98a69865e8
Signed by: orion
GPG Key ID: 6D4165AE4C928719
4 changed files with 15 additions and 10 deletions

View File

@ -1,11 +1,11 @@
import { Buffer } from 'node:buffer'
/** @type {(offset: number) => (b: Buffer) => bigint} */
export const readBigUInt64BE = off => b => b.readBigUInt64BE(off)
export const readBigInt64BE = off => b => b.readBigInt64BE(off)
/** @type {(b: bigint) => Buffer} */
export const fromBigUInt64BE = b => {
export const fromBigInt64BE = b => {
const buf = Buffer.alloc(8)
buf.writeBigUInt64BE(b)
buf.writeBigInt64BE(b)
return buf
}

View File

@ -3,5 +3,5 @@ module Data.Buffer.Immutable.BigInt where
import JS.BigInt (BigInt)
import Node.Buffer.Immutable (ImmutableBuffer)
foreign import readBigUInt64BE :: Int -> ImmutableBuffer -> BigInt
foreign import fromBigUInt64BE :: BigInt -> ImmutableBuffer
foreign import readBigInt64BE :: Int -> ImmutableBuffer -> BigInt
foreign import fromBigInt64BE :: BigInt -> ImmutableBuffer

View File

@ -256,21 +256,21 @@ fromString s = map (trim <<< Proquint) $ traverse segmentFromString $ String.spl
fromInt :: Int -> Proquint
fromInt n = fromBits $ unsafePerformEffect do
buf <- Buffer.alloc 4
Buffer.write Buffer.UInt32BE (Int.toNumber n) 0 buf
Buffer.write Buffer.Int32BE (Int.toNumber n) 0 buf
Buffer.freeze buf
toInt :: Proquint -> Maybe Int
toInt pq@(Proquint segs)
| Array.length segs <= 2 = Int.fromNumber $ Buffer.Immutable.read UInt32BE 0 $ toBits $ pad 2 pq
| Array.length segs <= 2 = Int.fromNumber $ Buffer.Immutable.read Int32BE 0 $ toBits $ pad 2 pq
| otherwise = Nothing
toBigInt :: Proquint -> Maybe BigInt
toBigInt pq@(Proquint segs)
| Array.length segs <= 4 = Just $ Buffer.Immutable.BigInt.readBigUInt64BE 0 $ toBits $ pad 4 pq
| Array.length segs <= 4 = Just $ Buffer.Immutable.BigInt.readBigInt64BE 0 $ toBits $ pad 4 pq
| otherwise = Nothing
fromBigInt :: BigInt -> Proquint
fromBigInt b = fromBits $ Buffer.Immutable.BigInt.fromBigUInt64BE b
fromBigInt b = fromBits $ Buffer.Immutable.BigInt.fromBigInt64BE b
toBits :: Proquint -> ImmutableBuffer
toBits (Proquint segments) = unsafePerformEffect do

View File

@ -46,7 +46,12 @@ genBigInt =
bit true = "1"
bit false = "0"
in
map (bigintFromString <<< boolArrayToBinary) $ sequence $ Array.replicate 64 (arbitrary @Boolean)
do
sign <- map (if _ then identity else negate) $ arbitrary @Boolean
map (sign <<< bigintFromString <<< boolArrayToBinary)
$ sequence
$ Array.replicate 63
$ arbitrary @Boolean
newtype TestCon = TestCon Con