From ca6ccbd09f2e9e6778ddb2e45d75ee0de8bfaad8 Mon Sep 17 00:00:00 2001 From: Ruslan Akhtariev <46343690+RusAkh@users.noreply.github.com> Date: Thu, 22 Dec 2022 05:16:19 +0100 Subject: [PATCH] osmomath: `AddMut` and `QuoMut` (#3779) * mut add * test add mut * quo mut * test quo mut/ remove want from test struct * refactor exp * change mutatives code * change * not allocaing * exp change to quomut * remove file * refactor quo * refactor ad * refactor tests --- osmomath/decimal.go | 34 ++++++++++++++++++++--------- osmomath/decimal_test.go | 47 ++++++++++++++++++++++++++++++++++++++++ osmomath/exp2.go | 6 ++--- 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/osmomath/decimal.go b/osmomath/decimal.go index a5735a55e00..cf921f494b1 100644 --- a/osmomath/decimal.go +++ b/osmomath/decimal.go @@ -240,12 +240,20 @@ func (d BigDec) BigInt() *big.Int { // addition func (d BigDec) Add(d2 BigDec) BigDec { - res := new(big.Int).Add(d.i, d2.i) + copy := d.Clone() + copy.AddMut(d2) + return copy +} - if res.BitLen() > maxDecBitLen { +// mutative addition +func (d BigDec) AddMut(d2 BigDec) BigDec { + d.i.Add(d.i, d2.i) + + if d.i.BitLen() > maxDecBitLen { panic("Int overflow") } - return BigDec{res} + + return d } // subtraction @@ -319,19 +327,25 @@ func (d BigDec) MulInt64(i int64) BigDec { // quotient func (d BigDec) Quo(d2 BigDec) BigDec { + copy := d.Clone() + copy.QuoMut(d2) + return copy +} + +// mutative quotient +func (d BigDec) QuoMut(d2 BigDec) BigDec { // multiply precision twice - mul := new(big.Int).Mul(d.i, precisionReuse) - mul.Mul(mul, precisionReuse) + d.i.Mul(d.i, precisionReuse) + d.i.Mul(d.i, precisionReuse) - quo := new(big.Int).Quo(mul, d2.i) - chopped := chopPrecisionAndRound(quo) + d.i.Quo(d.i, d2.i) + chopPrecisionAndRound(d.i) - if chopped.BitLen() > maxDecBitLen { + if d.i.BitLen() > maxDecBitLen { panic("Int overflow") } - return BigDec{chopped} + return d } - func (d BigDec) QuoRaw(d2 int64) BigDec { // multiply precision, so we can chop it later mul := new(big.Int).Mul(d.i, precisionReuse) diff --git a/osmomath/decimal_test.go b/osmomath/decimal_test.go index dbaa6839a14..7961637dbbe 100644 --- a/osmomath/decimal_test.go +++ b/osmomath/decimal_test.go @@ -43,6 +43,53 @@ func (s *decimalTestSuite) assertMutResult(expectedResult, startValue, mutativeR s.Require().Equal(nonMutativeStartValue, startValue) } +func (s *decimalTestSuite) TestAddMut() { + toAdd := osmomath.MustNewDecFromStr("10") + tests := map[string]struct { + startValue osmomath.BigDec + expectedMutResult osmomath.BigDec + }{ + "0": {osmomath.NewBigDec(0), osmomath.NewBigDec(10)}, + "1": {osmomath.NewBigDec(1), osmomath.NewBigDec(11)}, + "10": {osmomath.NewBigDec(10), osmomath.NewBigDec(20)}, + } + + for name, tc := range tests { + s.Run(name, func() { + startMut := tc.startValue.Clone() + startNonMut := tc.startValue.Clone() + + resultMut := startMut.AddMut(toAdd) + resultNonMut := startNonMut.Add(toAdd) + + s.assertMutResult(tc.expectedMutResult, tc.startValue, resultMut, resultNonMut, startMut, startNonMut) + }) + } +} + +func (s *decimalTestSuite) TestQuoMut() { + quoBy := osmomath.MustNewDecFromStr("2") + tests := map[string]struct { + startValue osmomath.BigDec + expectedMutResult osmomath.BigDec + }{ + "0": {osmomath.NewBigDec(0), osmomath.NewBigDec(0)}, + "1": {osmomath.NewBigDec(1), osmomath.MustNewDecFromStr("0.5")}, + "10": {osmomath.NewBigDec(10), osmomath.NewBigDec(5)}, + } + + for name, tc := range tests { + s.Run(name, func() { + startMut := tc.startValue.Clone() + startNonMut := tc.startValue.Clone() + + resultMut := startMut.QuoMut(quoBy) + resultNonMut := startNonMut.Quo(quoBy) + + s.assertMutResult(tc.expectedMutResult, tc.startValue, resultMut, resultNonMut, startMut, startNonMut) + }) + } +} func TestDecApproxEq(t *testing.T) { // d1 = 0.55, d2 = 0.6, tol = 0.1 d1 := osmomath.NewDecWithPrec(55, 2) diff --git a/osmomath/exp2.go b/osmomath/exp2.go index b7973b3bc62..39b2333ebd3 100644 --- a/osmomath/exp2.go +++ b/osmomath/exp2.go @@ -93,9 +93,9 @@ func exp2ChebyshevRationalApprox(x BigDec) BigDec { for i := 1; i < len(numeratorCoefficients13Param); i++ { x_exp_i.MulMut(x) - h_x = h_x.Add(numeratorCoefficients13Param[i].Mul(x_exp_i)) - p_x = p_x.Add(denominatorCoefficients13Param[i].Mul(x_exp_i)) + h_x.AddMut(numeratorCoefficients13Param[i].Mul(x_exp_i)) + p_x.AddMut(denominatorCoefficients13Param[i].Mul(x_exp_i)) } - return h_x.Quo(p_x) + return h_x.QuoMut(p_x) }