@@ -4,6 +4,10 @@ import std/[algorithm, bitops, math, options]
44
55type
66 BigInt * = object
7+ # # An arbitrary precision integer.
8+ # Invariants for `a: BigInt`:
9+ # * if `a` is non-zero: `a.limbs[a.limbs.high] != 0`
10+ # * if `a` is zero: `a.limbs.len <= 1`
711 limbs: seq [uint32 ]
812 isNegative: bool
913
@@ -23,6 +27,7 @@ func initBigInt*(vals: sink seq[uint32], isNegative = false): BigInt =
2327 assert $ a == $ b
2428 result .limbs = vals
2529 result .isNegative = isNegative
30+ normalize (result )
2631
2732func initBigInt * [T: int8 | int16 | int32 ](val: T): BigInt =
2833 if val < 0 :
6671 one = initBigInt (1 )
6772
6873func isZero (a: BigInt ): bool {.inline .} =
69- for i in countdown (a.limbs.high, 0 ):
70- if a.limbs[i] != 0 'u32 :
71- return false
72- return true
74+ a.limbs.len == 0 or (a.limbs.len == 1 and a.limbs[0 ] == 0 )
7375
7476func abs * (a: BigInt ): BigInt =
7577 # Returns the absolute value of `a`.
@@ -532,6 +534,7 @@ func `and`*(a, b: BigInt): BigInt =
532534 # # Bitwise `and` for `BigInt`s.
533535 assert (not a.isNegative) and (not b.isNegative)
534536 bitwiseAnd (result , a, b)
537+ normalize (result )
535538
536539func bitwiseOr (a: var BigInt , b, c: BigInt ) =
537540 # `b` must be smaller than `c`
@@ -564,6 +567,7 @@ func `xor`*(a, b: BigInt): BigInt =
564567 bitwiseXor (result , a, b)
565568 else :
566569 bitwiseXor (result , b, a)
570+ normalize (result )
567571
568572func reset (a: var BigInt ) =
569573 # # Resets a `BigInt` back to the zero value.
0 commit comments