Skip to content

Commit

Permalink
apd: add property based testing to assert that BigInt == big.Int
Browse files Browse the repository at this point in the history
This commit uses Golang's `testing/quick` package to exercise each of the
methods in the shared `BigInt` and `big.Int` interface and assert that
each implementation behaves identically under all inputs.

This testing caught a few minor issues around graceful handling of nil
receivers in unused methods. I confirmed that it would have been able
to find a more serious correctness issue with `BigInt.Sign` that I did
not catch until attempting to integrate the library with CockroachDB.
  • Loading branch information
nvanbenschoten committed Jan 6, 2022
1 parent 53c5c82 commit 22a1de8
Show file tree
Hide file tree
Showing 2 changed files with 841 additions and 5 deletions.
16 changes: 11 additions & 5 deletions bigint.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,18 @@ func mulInline(xVal, yVal uint, xNeg, yNeg bool) (zVal uint, zNeg, ok bool) {
}

func quoInline(xVal, yVal uint, xNeg, yNeg bool) (quoVal uint, quoNeg, ok bool) {
if yVal == 0 { // divide by 0
return 0, false, false
}
quo := xVal / yVal
neg := xNeg != yNeg
return quo, neg, true
}

func remInline(xVal, yVal uint, xNeg, yNeg bool) (remVal uint, remNeg, ok bool) {
if yVal == 0 { // divide by 0
return 0, false, false
}
rem := xVal % yVal
return rem, xNeg, true
}
Expand Down Expand Up @@ -356,7 +362,7 @@ func (z *BigInt) AndNot(x, y *BigInt) *BigInt {
// Append calls (big.Int).Append.
func (z *BigInt) Append(buf []byte, base int) []byte {
var tmp1 big.Int
return z.inner(&tmp1).Append(buf, base)
return z.innerOrNil(&tmp1).Append(buf, base)
}

// Binomial calls (big.Int).Binomial.
Expand Down Expand Up @@ -771,10 +777,10 @@ func (z *BigInt) Set(x *BigInt) *BigInt {
}

// SetBit calls (big.Int).SetBit.
func (z *BigInt) SetBit(x *BigInt, i int, v uint) *BigInt {
func (z *BigInt) SetBit(x *BigInt, i int, b uint) *BigInt {
var tmp1, tmp2 big.Int
zi := z.inner(&tmp1)
zi.SetBit(x.inner(&tmp2), i, v)
zi.SetBit(x.inner(&tmp2), i, b)
z.updateInner(zi)
return z
}
Expand Down Expand Up @@ -864,7 +870,7 @@ func (z *BigInt) Sqrt(x *BigInt) *BigInt {
// String calls (big.Int).String.
func (z *BigInt) String() string {
var tmp1 big.Int
return z.inner(&tmp1).String()
return z.innerOrNil(&tmp1).String()
}

// Sub calls (big.Int).Sub.
Expand All @@ -887,7 +893,7 @@ func (z *BigInt) Sub(x, y *BigInt) *BigInt {
// Text calls (big.Int).Text.
func (z *BigInt) Text(base int) string {
var tmp1 big.Int
return z.inner(&tmp1).Text(base)
return z.innerOrNil(&tmp1).Text(base)
}

// TrailingZeroBits calls (big.Int).TrailingZeroBits.
Expand Down
Loading

0 comments on commit 22a1de8

Please sign in to comment.