Skip to content

Commit 910f7ff

Browse files
authored
Always normalize (#104)
1 parent b96c321 commit 910f7ff

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

src/bigints.nim

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ import std/[algorithm, bitops, math, options]
44

55
type
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

2732
func initBigInt*[T: int8|int16|int32](val: T): BigInt =
2833
if val < 0:
@@ -66,10 +71,7 @@ const
6671
one = initBigInt(1)
6772

6873
func 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

7476
func 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

536539
func 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

568572
func reset(a: var BigInt) =
569573
## Resets a `BigInt` back to the zero value.

0 commit comments

Comments
 (0)