Skip to content

Commit

Permalink
add rounding tests
Browse files Browse the repository at this point in the history
  • Loading branch information
robert-zaremba committed Jul 19, 2023
1 parent c238b64 commit ce62625
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 10 deletions.
16 changes: 11 additions & 5 deletions util/bpmath/bp.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,22 @@ import (
"math"

cmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// BP represents values in basis points. Maximum value is 2^32-1.
// Note: BP operations should not be chained - this causes precision losses.
type BP uint32

func (bp BP) ToDec() sdk.Dec {
return sdk.NewDecWithPrec(int64(bp), 4)
}

// Mul return a*bp rounding towards zero.
func (bp BP) Mul(a cmath.Int) cmath.Int {
return Mul(a, bp)
}

// FromQuo returns a/b in basis points.
// Contract: a>=0 and b > 0.
// Panics if a/b >= MaxUint32/10'000 or if b==0.
Expand All @@ -32,7 +42,7 @@ func quo(a, b cmath.Int, rounding Rounding, max uint64) uint64 {
return x
}

// Mul returns a * b_basis_points
// Mul returns a * b_basis_points rounding towards zero.
// Contract: b in [0, MaxUint32]
func Mul[T BP | FixedBP](a cmath.Int, b T) cmath.Int {
if b == 0 {
Expand All @@ -43,7 +53,3 @@ func Mul[T BP | FixedBP](a cmath.Int, b T) cmath.Int {
}
return a.MulRaw(int64(b)).Quo(oneBigInt)
}

func (bp BP) ToDec() cmath.LegacyDec {
return cmath.LegacyNewDecWithPrec(int64(bp), 4)
}
10 changes: 10 additions & 0 deletions util/bpmath/bp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,14 @@ func TestInt(t *testing.T) {
require.Equal(sresult, sdk.NewInt(12))
mresult = Mul(mi, bp)
require.Equal(mresult, math.NewInt(12))

// test rounding
si = sdk.NewInt(1299)
require.Equal(bp.Mul(si), sdk.NewInt(12))

si = sdk.NewInt(-1299)
require.Equal(bp.Mul(si), sdk.NewInt(-12))

si = sdk.NewInt(-1201)
require.Equal(bp.Mul(si), sdk.NewInt(-12))
}
6 changes: 3 additions & 3 deletions util/bpmath/doc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Package bpmath provides types and functions for doing basis point operations.
// There is no precision lost for operations like `a * b` where `a` or `b` is basis points,
// and the other variable is `Int`.
// Package bpmath provides types and functions for doing basis point operations with math.Int.
// So, the result is always math.Int, and follows the Go rounding semantic for integer nubmer:
// rounds towards zero.
package bpmath
10 changes: 8 additions & 2 deletions util/bpmath/fixed_bp.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bpmath

import (
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// FixedBP assures that all operations are in 0-10'000 range
Expand All @@ -15,6 +16,11 @@ func FixedFromQuo(dividend, divisor math.Int, rounding Rounding) FixedBP {
return FixedBP(quo(dividend, divisor, rounding, One))
}

func (bp FixedBP) ToDec() math.LegacyDec {
return math.LegacyNewDecWithPrec(int64(bp), 4)
func (bp FixedBP) ToDec() sdk.Dec {
return sdk.NewDecWithPrec(int64(bp), 4)
}

// Mul return a*bp rounding towards zero.
func (bp FixedBP) Mul(a math.Int) math.Int {
return Mul(a, bp)
}

0 comments on commit ce62625

Please sign in to comment.