github.com/Finschia/finschia-sdk@v0.48.1/types/decimal_test.go (about)

     1  package types_test
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"math/big"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/stretchr/testify/suite"
    12  	"gopkg.in/yaml.v2"
    13  
    14  	sdk "github.com/Finschia/finschia-sdk/types"
    15  )
    16  
    17  type decimalTestSuite struct {
    18  	suite.Suite
    19  }
    20  
    21  func TestDecimalTestSuite(t *testing.T) {
    22  	suite.Run(t, new(decimalTestSuite))
    23  }
    24  
    25  // create a decimal from a decimal string (ex. "1234.5678")
    26  func (s *decimalTestSuite) mustNewDecFromStr(str string) (d sdk.Dec) {
    27  	d, err := sdk.NewDecFromStr(str)
    28  	s.Require().NoError(err)
    29  
    30  	return d
    31  }
    32  
    33  func (s *decimalTestSuite) TestNewDecFromStr() {
    34  	largeBigInt, ok := new(big.Int).SetString("3144605511029693144278234343371835", 10)
    35  	s.Require().True(ok)
    36  
    37  	largerBigInt, ok := new(big.Int).SetString("8888888888888888888888888888888888888888888888888888888888888888888844444440", 10)
    38  	s.Require().True(ok)
    39  
    40  	largestBigInt, ok := new(big.Int).SetString("33499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
    41  	s.Require().True(ok)
    42  
    43  	tests := []struct {
    44  		decimalStr string
    45  		expErr     bool
    46  		exp        sdk.Dec
    47  	}{
    48  		{"", true, sdk.Dec{}},
    49  		{"0.-75", true, sdk.Dec{}},
    50  		{"0", false, sdk.NewDec(0)},
    51  		{"1", false, sdk.NewDec(1)},
    52  		{"1.1", false, sdk.NewDecWithPrec(11, 1)},
    53  		{"0.75", false, sdk.NewDecWithPrec(75, 2)},
    54  		{"0.8", false, sdk.NewDecWithPrec(8, 1)},
    55  		{"0.11111", false, sdk.NewDecWithPrec(11111, 5)},
    56  		{"314460551102969.3144278234343371835", true, sdk.NewDec(3141203149163817869)},
    57  		{
    58  			"314460551102969314427823434337.1835718092488231350",
    59  			true, sdk.NewDecFromBigIntWithPrec(largeBigInt, 4),
    60  		},
    61  		{
    62  			"314460551102969314427823434337.1835",
    63  			false, sdk.NewDecFromBigIntWithPrec(largeBigInt, 4),
    64  		},
    65  		{".", true, sdk.Dec{}},
    66  		{".0", true, sdk.NewDec(0)},
    67  		{"1.", true, sdk.NewDec(1)},
    68  		{"foobar", true, sdk.Dec{}},
    69  		{"0.foobar", true, sdk.Dec{}},
    70  		{"0.foobar.", true, sdk.Dec{}},
    71  		{"8888888888888888888888888888888888888888888888888888888888888888888844444440", false, sdk.NewDecFromBigInt(largerBigInt)},
    72  		{"33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535", false, sdk.NewDecFromBigIntWithPrec(largestBigInt, 18)},
    73  		{"133499189745056880149688856635597007162669032647290798121690100488888732861291", true, sdk.Dec{}},
    74  	}
    75  
    76  	for tcIndex, tc := range tests {
    77  		res, err := sdk.NewDecFromStr(tc.decimalStr)
    78  		if tc.expErr {
    79  			s.Require().NotNil(err, "error expected, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    80  		} else {
    81  			s.Require().Nil(err, "unexpected error, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    82  			s.Require().True(res.Equal(tc.exp), "equality was incorrect, res %v, exp %v, tc %v", res, tc.exp, tcIndex)
    83  		}
    84  
    85  		// negative tc
    86  		res, err = sdk.NewDecFromStr("-" + tc.decimalStr)
    87  		if tc.expErr {
    88  			s.Require().NotNil(err, "error expected, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    89  		} else {
    90  			s.Require().Nil(err, "unexpected error, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    91  			exp := tc.exp.Mul(sdk.NewDec(-1))
    92  			s.Require().True(res.Equal(exp), "equality was incorrect, res %v, exp %v, tc %v", res, exp, tcIndex)
    93  		}
    94  	}
    95  }
    96  
    97  func (s *decimalTestSuite) TestDecString() {
    98  	tests := []struct {
    99  		d    sdk.Dec
   100  		want string
   101  	}{
   102  		{sdk.NewDec(0), "0.000000000000000000"},
   103  		{sdk.NewDec(1), "1.000000000000000000"},
   104  		{sdk.NewDec(10), "10.000000000000000000"},
   105  		{sdk.NewDec(12340), "12340.000000000000000000"},
   106  		{sdk.NewDecWithPrec(12340, 4), "1.234000000000000000"},
   107  		{sdk.NewDecWithPrec(12340, 5), "0.123400000000000000"},
   108  		{sdk.NewDecWithPrec(12340, 8), "0.000123400000000000"},
   109  		{sdk.NewDecWithPrec(1009009009009009009, 17), "10.090090090090090090"},
   110  	}
   111  	for tcIndex, tc := range tests {
   112  		s.Require().Equal(tc.want, tc.d.String(), "bad String(), index: %v", tcIndex)
   113  	}
   114  }
   115  
   116  func (s *decimalTestSuite) TestDecFloat64() {
   117  	tests := []struct {
   118  		d    sdk.Dec
   119  		want float64
   120  	}{
   121  		{sdk.NewDec(0), 0.000000000000000000},
   122  		{sdk.NewDec(1), 1.000000000000000000},
   123  		{sdk.NewDec(10), 10.000000000000000000},
   124  		{sdk.NewDec(12340), 12340.000000000000000000},
   125  		{sdk.NewDecWithPrec(12340, 4), 1.234000000000000000},
   126  		{sdk.NewDecWithPrec(12340, 5), 0.123400000000000000},
   127  		{sdk.NewDecWithPrec(12340, 8), 0.000123400000000000},
   128  		{sdk.NewDecWithPrec(1009009009009009009, 17), 10.090090090090090090},
   129  	}
   130  	for tcIndex, tc := range tests {
   131  		value, err := tc.d.Float64()
   132  		s.Require().Nil(err, "error getting Float64(), index: %v", tcIndex)
   133  		s.Require().Equal(tc.want, value, "bad Float64(), index: %v", tcIndex)
   134  		s.Require().Equal(tc.want, tc.d.MustFloat64(), "bad MustFloat64(), index: %v", tcIndex)
   135  	}
   136  }
   137  
   138  func (s *decimalTestSuite) TestEqualities() {
   139  	tests := []struct {
   140  		d1, d2     sdk.Dec
   141  		gt, lt, eq bool
   142  	}{
   143  		{sdk.NewDec(0), sdk.NewDec(0), false, false, true},
   144  		{sdk.NewDecWithPrec(0, 2), sdk.NewDecWithPrec(0, 4), false, false, true},
   145  		{sdk.NewDecWithPrec(100, 0), sdk.NewDecWithPrec(100, 0), false, false, true},
   146  		{sdk.NewDecWithPrec(-100, 0), sdk.NewDecWithPrec(-100, 0), false, false, true},
   147  		{sdk.NewDecWithPrec(-1, 1), sdk.NewDecWithPrec(-1, 1), false, false, true},
   148  		{sdk.NewDecWithPrec(3333, 3), sdk.NewDecWithPrec(3333, 3), false, false, true},
   149  
   150  		{sdk.NewDecWithPrec(0, 0), sdk.NewDecWithPrec(3333, 3), false, true, false},
   151  		{sdk.NewDecWithPrec(0, 0), sdk.NewDecWithPrec(100, 0), false, true, false},
   152  		{sdk.NewDecWithPrec(-1, 0), sdk.NewDecWithPrec(3333, 3), false, true, false},
   153  		{sdk.NewDecWithPrec(-1, 0), sdk.NewDecWithPrec(100, 0), false, true, false},
   154  		{sdk.NewDecWithPrec(1111, 3), sdk.NewDecWithPrec(100, 0), false, true, false},
   155  		{sdk.NewDecWithPrec(1111, 3), sdk.NewDecWithPrec(3333, 3), false, true, false},
   156  		{sdk.NewDecWithPrec(-3333, 3), sdk.NewDecWithPrec(-1111, 3), false, true, false},
   157  
   158  		{sdk.NewDecWithPrec(3333, 3), sdk.NewDecWithPrec(0, 0), true, false, false},
   159  		{sdk.NewDecWithPrec(100, 0), sdk.NewDecWithPrec(0, 0), true, false, false},
   160  		{sdk.NewDecWithPrec(3333, 3), sdk.NewDecWithPrec(-1, 0), true, false, false},
   161  		{sdk.NewDecWithPrec(100, 0), sdk.NewDecWithPrec(-1, 0), true, false, false},
   162  		{sdk.NewDecWithPrec(100, 0), sdk.NewDecWithPrec(1111, 3), true, false, false},
   163  		{sdk.NewDecWithPrec(3333, 3), sdk.NewDecWithPrec(1111, 3), true, false, false},
   164  		{sdk.NewDecWithPrec(-1111, 3), sdk.NewDecWithPrec(-3333, 3), true, false, false},
   165  	}
   166  
   167  	for tcIndex, tc := range tests {
   168  		s.Require().Equal(tc.gt, tc.d1.GT(tc.d2), "GT result is incorrect, tc %d", tcIndex)
   169  		s.Require().Equal(tc.lt, tc.d1.LT(tc.d2), "LT result is incorrect, tc %d", tcIndex)
   170  		s.Require().Equal(tc.eq, tc.d1.Equal(tc.d2), "equality result is incorrect, tc %d", tcIndex)
   171  	}
   172  }
   173  
   174  func (s *decimalTestSuite) TestDecsEqual() {
   175  	tests := []struct {
   176  		d1s, d2s []sdk.Dec
   177  		eq       bool
   178  	}{
   179  		{[]sdk.Dec{sdk.NewDec(0)}, []sdk.Dec{sdk.NewDec(0)}, true},
   180  		{[]sdk.Dec{sdk.NewDec(0)}, []sdk.Dec{sdk.NewDec(1)}, false},
   181  		{[]sdk.Dec{sdk.NewDec(0)}, []sdk.Dec{}, false},
   182  		{[]sdk.Dec{sdk.NewDec(0), sdk.NewDec(1)}, []sdk.Dec{sdk.NewDec(0), sdk.NewDec(1)}, true},
   183  		{[]sdk.Dec{sdk.NewDec(1), sdk.NewDec(0)}, []sdk.Dec{sdk.NewDec(1), sdk.NewDec(0)}, true},
   184  		{[]sdk.Dec{sdk.NewDec(1), sdk.NewDec(0)}, []sdk.Dec{sdk.NewDec(0), sdk.NewDec(1)}, false},
   185  		{[]sdk.Dec{sdk.NewDec(1), sdk.NewDec(0)}, []sdk.Dec{sdk.NewDec(1)}, false},
   186  		{[]sdk.Dec{sdk.NewDec(1), sdk.NewDec(2)}, []sdk.Dec{sdk.NewDec(2), sdk.NewDec(4)}, false},
   187  		{[]sdk.Dec{sdk.NewDec(3), sdk.NewDec(18)}, []sdk.Dec{sdk.NewDec(1), sdk.NewDec(6)}, false},
   188  	}
   189  
   190  	for tcIndex, tc := range tests {
   191  		s.Require().Equal(tc.eq, sdk.DecsEqual(tc.d1s, tc.d2s), "equality of decional arrays is incorrect, tc %d", tcIndex)
   192  		s.Require().Equal(tc.eq, sdk.DecsEqual(tc.d2s, tc.d1s), "equality of decional arrays is incorrect (converse), tc %d", tcIndex)
   193  	}
   194  }
   195  
   196  func (s *decimalTestSuite) TestArithmetic() {
   197  	tests := []struct {
   198  		d1, d2                                sdk.Dec
   199  		expMul, expMulTruncate                sdk.Dec
   200  		expQuo, expQuoRoundUp, expQuoTruncate sdk.Dec
   201  		expAdd, expSub                        sdk.Dec
   202  	}{
   203  		//  d1         d2         MUL    MulTruncate    QUO    QUORoundUp QUOTrunctate  ADD         SUB
   204  		{sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0)},
   205  		{sdk.NewDec(1), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(1), sdk.NewDec(1)},
   206  		{sdk.NewDec(0), sdk.NewDec(1), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(1), sdk.NewDec(-1)},
   207  		{sdk.NewDec(0), sdk.NewDec(-1), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(-1), sdk.NewDec(1)},
   208  		{sdk.NewDec(-1), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(0), sdk.NewDec(-1), sdk.NewDec(-1)},
   209  
   210  		{sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(2), sdk.NewDec(0)},
   211  		{sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(-2), sdk.NewDec(0)},
   212  		{sdk.NewDec(1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(0), sdk.NewDec(2)},
   213  		{sdk.NewDec(-1), sdk.NewDec(1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(-1), sdk.NewDec(0), sdk.NewDec(-2)},
   214  
   215  		{
   216  			sdk.NewDec(3), sdk.NewDec(7), sdk.NewDec(21), sdk.NewDec(21),
   217  			sdk.NewDecWithPrec(428571428571428571, 18), sdk.NewDecWithPrec(428571428571428572, 18), sdk.NewDecWithPrec(428571428571428571, 18),
   218  			sdk.NewDec(10), sdk.NewDec(-4),
   219  		},
   220  		{
   221  			sdk.NewDec(2), sdk.NewDec(4), sdk.NewDec(8), sdk.NewDec(8), sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1), sdk.NewDecWithPrec(5, 1),
   222  			sdk.NewDec(6), sdk.NewDec(-2),
   223  		},
   224  
   225  		{sdk.NewDec(100), sdk.NewDec(100), sdk.NewDec(10000), sdk.NewDec(10000), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(200), sdk.NewDec(0)},
   226  
   227  		{
   228  			sdk.NewDecWithPrec(15, 1), sdk.NewDecWithPrec(15, 1), sdk.NewDecWithPrec(225, 2), sdk.NewDecWithPrec(225, 2),
   229  			sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(1), sdk.NewDec(3), sdk.NewDec(0),
   230  		},
   231  		{
   232  			sdk.NewDecWithPrec(3333, 4), sdk.NewDecWithPrec(333, 4), sdk.NewDecWithPrec(1109889, 8), sdk.NewDecWithPrec(1109889, 8),
   233  			sdk.MustNewDecFromStr("10.009009009009009009"), sdk.MustNewDecFromStr("10.009009009009009010"), sdk.MustNewDecFromStr("10.009009009009009009"),
   234  			sdk.NewDecWithPrec(3666, 4), sdk.NewDecWithPrec(3, 1),
   235  		},
   236  	}
   237  
   238  	for tcIndex, tc := range tests {
   239  		tc := tc
   240  		resAdd := tc.d1.Add(tc.d2)
   241  		resSub := tc.d1.Sub(tc.d2)
   242  		resMul := tc.d1.Mul(tc.d2)
   243  		resMulTruncate := tc.d1.MulTruncate(tc.d2)
   244  		s.Require().True(tc.expAdd.Equal(resAdd), "exp %v, res %v, tc %d", tc.expAdd, resAdd, tcIndex)
   245  		s.Require().True(tc.expSub.Equal(resSub), "exp %v, res %v, tc %d", tc.expSub, resSub, tcIndex)
   246  		s.Require().True(tc.expMul.Equal(resMul), "exp %v, res %v, tc %d", tc.expMul, resMul, tcIndex)
   247  		s.Require().True(tc.expMulTruncate.Equal(resMulTruncate), "exp %v, res %v, tc %d", tc.expMulTruncate, resMulTruncate, tcIndex)
   248  
   249  		if tc.d2.IsZero() { // panic for divide by zero
   250  			s.Require().Panics(func() { tc.d1.Quo(tc.d2) })
   251  		} else {
   252  			resQuo := tc.d1.Quo(tc.d2)
   253  			s.Require().True(tc.expQuo.Equal(resQuo), "exp %v, res %v, tc %d", tc.expQuo.String(), resQuo.String(), tcIndex)
   254  
   255  			resQuoRoundUp := tc.d1.QuoRoundUp(tc.d2)
   256  			s.Require().True(tc.expQuoRoundUp.Equal(resQuoRoundUp), "exp %v, res %v, tc %d",
   257  				tc.expQuoRoundUp.String(), resQuoRoundUp.String(), tcIndex)
   258  
   259  			resQuoTruncate := tc.d1.QuoTruncate(tc.d2)
   260  			s.Require().True(tc.expQuoTruncate.Equal(resQuoTruncate), "exp %v, res %v, tc %d",
   261  				tc.expQuoTruncate.String(), resQuoTruncate.String(), tcIndex)
   262  		}
   263  	}
   264  }
   265  
   266  func (s *decimalTestSuite) TestBankerRoundChop() {
   267  	tests := []struct {
   268  		d1  sdk.Dec
   269  		exp int64
   270  	}{
   271  		{s.mustNewDecFromStr("0.25"), 0},
   272  		{s.mustNewDecFromStr("0"), 0},
   273  		{s.mustNewDecFromStr("1"), 1},
   274  		{s.mustNewDecFromStr("0.75"), 1},
   275  		{s.mustNewDecFromStr("0.5"), 0},
   276  		{s.mustNewDecFromStr("7.5"), 8},
   277  		{s.mustNewDecFromStr("1.5"), 2},
   278  		{s.mustNewDecFromStr("2.5"), 2},
   279  		{s.mustNewDecFromStr("0.545"), 1}, // 0.545-> 1 even though 5 is first decimal and 1 not even
   280  		{s.mustNewDecFromStr("1.545"), 2},
   281  	}
   282  
   283  	for tcIndex, tc := range tests {
   284  		resNeg := tc.d1.Neg().RoundInt64()
   285  		s.Require().Equal(-1*tc.exp, resNeg, "negative tc %d", tcIndex)
   286  
   287  		resPos := tc.d1.RoundInt64()
   288  		s.Require().Equal(tc.exp, resPos, "positive tc %d", tcIndex)
   289  	}
   290  }
   291  
   292  func (s *decimalTestSuite) TestTruncate() {
   293  	tests := []struct {
   294  		d1  sdk.Dec
   295  		exp int64
   296  	}{
   297  		{s.mustNewDecFromStr("0"), 0},
   298  		{s.mustNewDecFromStr("0.25"), 0},
   299  		{s.mustNewDecFromStr("0.75"), 0},
   300  		{s.mustNewDecFromStr("1"), 1},
   301  		{s.mustNewDecFromStr("1.5"), 1},
   302  		{s.mustNewDecFromStr("7.5"), 7},
   303  		{s.mustNewDecFromStr("7.6"), 7},
   304  		{s.mustNewDecFromStr("7.4"), 7},
   305  		{s.mustNewDecFromStr("100.1"), 100},
   306  		{s.mustNewDecFromStr("1000.1"), 1000},
   307  	}
   308  
   309  	for tcIndex, tc := range tests {
   310  		resNeg := tc.d1.Neg().TruncateInt64()
   311  		s.Require().Equal(-1*tc.exp, resNeg, "negative tc %d", tcIndex)
   312  
   313  		resPos := tc.d1.TruncateInt64()
   314  		s.Require().Equal(tc.exp, resPos, "positive tc %d", tcIndex)
   315  	}
   316  }
   317  
   318  func (s *decimalTestSuite) TestStringOverflow() {
   319  	// two random 64 bit primes
   320  	dec1, err := sdk.NewDecFromStr("51643150036226787134389711697696177267")
   321  	s.Require().NoError(err)
   322  	dec2, err := sdk.NewDecFromStr("-31798496660535729618459429845579852627")
   323  	s.Require().NoError(err)
   324  	dec3 := dec1.Add(dec2)
   325  	s.Require().Equal(
   326  		"19844653375691057515930281852116324640.000000000000000000",
   327  		dec3.String(),
   328  	)
   329  }
   330  
   331  func (s *decimalTestSuite) TestDecMulInt() {
   332  	tests := []struct {
   333  		sdkDec sdk.Dec
   334  		sdkInt sdk.Int
   335  		want   sdk.Dec
   336  	}{
   337  		{sdk.NewDec(10), sdk.NewInt(2), sdk.NewDec(20)},
   338  		{sdk.NewDec(1000000), sdk.NewInt(100), sdk.NewDec(100000000)},
   339  		{sdk.NewDecWithPrec(1, 1), sdk.NewInt(10), sdk.NewDec(1)},
   340  		{sdk.NewDecWithPrec(1, 5), sdk.NewInt(20), sdk.NewDecWithPrec(2, 4)},
   341  	}
   342  	for i, tc := range tests {
   343  		got := tc.sdkDec.MulInt(tc.sdkInt)
   344  		s.Require().Equal(tc.want, got, "Incorrect result on test case %d", i)
   345  	}
   346  }
   347  
   348  func (s *decimalTestSuite) TestDecCeil() {
   349  	testCases := []struct {
   350  		input    sdk.Dec
   351  		expected sdk.Dec
   352  	}{
   353  		{sdk.NewDecWithPrec(1000000000000000, sdk.Precision), sdk.NewDec(1)},      // 0.001 => 1.0
   354  		{sdk.NewDecWithPrec(-1000000000000000, sdk.Precision), sdk.ZeroDec()},     // -0.001 => 0.0
   355  		{sdk.ZeroDec(), sdk.ZeroDec()},                                            // 0.0 => 0.0
   356  		{sdk.NewDecWithPrec(900000000000000000, sdk.Precision), sdk.NewDec(1)},    // 0.9 => 1.0
   357  		{sdk.NewDecWithPrec(4001000000000000000, sdk.Precision), sdk.NewDec(5)},   // 4.001 => 5.0
   358  		{sdk.NewDecWithPrec(-4001000000000000000, sdk.Precision), sdk.NewDec(-4)}, // -4.001 => -4.0
   359  		{sdk.NewDecWithPrec(4700000000000000000, sdk.Precision), sdk.NewDec(5)},   // 4.7 => 5.0
   360  		{sdk.NewDecWithPrec(-4700000000000000000, sdk.Precision), sdk.NewDec(-4)}, // -4.7 => -4.0
   361  	}
   362  
   363  	for i, tc := range testCases {
   364  		res := tc.input.Ceil()
   365  		s.Require().Equal(tc.expected, res, "unexpected result for test case %d, input: %v", i, tc.input)
   366  	}
   367  }
   368  
   369  func (s *decimalTestSuite) TestPower() {
   370  	testCases := []struct {
   371  		input    sdk.Dec
   372  		power    uint64
   373  		expected sdk.Dec
   374  	}{
   375  		{sdk.OneDec(), 10, sdk.OneDec()},                                                   // 1.0 ^ (10) => 1.0
   376  		{sdk.NewDecWithPrec(5, 1), 2, sdk.NewDecWithPrec(25, 2)},                           // 0.5 ^ 2 => 0.25
   377  		{sdk.NewDecWithPrec(2, 1), 2, sdk.NewDecWithPrec(4, 2)},                            // 0.2 ^ 2 => 0.04
   378  		{sdk.NewDecFromInt(sdk.NewInt(3)), 3, sdk.NewDecFromInt(sdk.NewInt(27))},           // 3 ^ 3 => 27
   379  		{sdk.NewDecFromInt(sdk.NewInt(-3)), 4, sdk.NewDecFromInt(sdk.NewInt(81))},          // -3 ^ 4 = 81
   380  		{sdk.NewDecWithPrec(1414213562373095049, 18), 2, sdk.NewDecFromInt(sdk.NewInt(2))}, // 1.414213562373095049 ^ 2 = 2
   381  	}
   382  
   383  	for i, tc := range testCases {
   384  		res := tc.input.Power(tc.power)
   385  		s.Require().True(tc.expected.Sub(res).Abs().LTE(sdk.SmallestDec()), "unexpected result for test case %d, input: %v", i, tc.input)
   386  	}
   387  }
   388  
   389  func (s *decimalTestSuite) TestApproxRoot() {
   390  	testCases := []struct {
   391  		input    sdk.Dec
   392  		root     uint64
   393  		expected sdk.Dec
   394  	}{
   395  		{sdk.OneDec(), 10, sdk.OneDec()},                                                       // 1.0 ^ (0.1) => 1.0
   396  		{sdk.NewDecWithPrec(25, 2), 2, sdk.NewDecWithPrec(5, 1)},                               // 0.25 ^ (0.5) => 0.5
   397  		{sdk.NewDecWithPrec(4, 2), 2, sdk.NewDecWithPrec(2, 1)},                                // 0.04 ^ (0.5) => 0.2
   398  		{sdk.NewDecFromInt(sdk.NewInt(27)), 3, sdk.NewDecFromInt(sdk.NewInt(3))},               // 27 ^ (1/3) => 3
   399  		{sdk.NewDecFromInt(sdk.NewInt(-81)), 4, sdk.NewDecFromInt(sdk.NewInt(-3))},             // -81 ^ (0.25) => -3
   400  		{sdk.NewDecFromInt(sdk.NewInt(2)), 2, sdk.NewDecWithPrec(1414213562373095049, 18)},     // 2 ^ (0.5) => 1.414213562373095049
   401  		{sdk.NewDecWithPrec(1005, 3), 31536000, sdk.MustNewDecFromStr("1.000000000158153904")}, // 1.005 ^ (1/31536000) ≈ 1.00000000016
   402  		{sdk.SmallestDec(), 2, sdk.NewDecWithPrec(1, 9)},                                       // 1e-18 ^ (0.5) => 1e-9
   403  		{sdk.SmallestDec(), 3, sdk.MustNewDecFromStr("0.000000999999999997")},                  // 1e-18 ^ (1/3) => 1e-6
   404  		{sdk.NewDecWithPrec(1, 8), 3, sdk.MustNewDecFromStr("0.002154434690031900")},           // 1e-8 ^ (1/3) ≈ 0.00215443469
   405  	}
   406  
   407  	// In the case of 1e-8 ^ (1/3), the result repeats every 5 iterations starting from iteration 24
   408  	// (i.e. 24, 29, 34, ... give the same result) and never converges enough. The maximum number of
   409  	// iterations (100) causes the result at iteration 100 to be returned, regardless of convergence.
   410  
   411  	for i, tc := range testCases {
   412  		res, err := tc.input.ApproxRoot(tc.root)
   413  		s.Require().NoError(err)
   414  		s.Require().True(tc.expected.Sub(res).Abs().LTE(sdk.SmallestDec()), "unexpected result for test case %d, input: %v", i, tc.input)
   415  	}
   416  }
   417  
   418  func (s *decimalTestSuite) TestApproxSqrt() {
   419  	testCases := []struct {
   420  		input    sdk.Dec
   421  		expected sdk.Dec
   422  	}{
   423  		{sdk.OneDec(), sdk.OneDec()},                                                    // 1.0 => 1.0
   424  		{sdk.NewDecWithPrec(25, 2), sdk.NewDecWithPrec(5, 1)},                           // 0.25 => 0.5
   425  		{sdk.NewDecWithPrec(4, 2), sdk.NewDecWithPrec(2, 1)},                            // 0.09 => 0.3
   426  		{sdk.NewDecFromInt(sdk.NewInt(9)), sdk.NewDecFromInt(sdk.NewInt(3))},            // 9 => 3
   427  		{sdk.NewDecFromInt(sdk.NewInt(-9)), sdk.NewDecFromInt(sdk.NewInt(-3))},          // -9 => -3
   428  		{sdk.NewDecFromInt(sdk.NewInt(2)), sdk.NewDecWithPrec(1414213562373095049, 18)}, // 2 => 1.414213562373095049
   429  	}
   430  
   431  	for i, tc := range testCases {
   432  		res, err := tc.input.ApproxSqrt()
   433  		s.Require().NoError(err)
   434  		s.Require().Equal(tc.expected, res, "unexpected result for test case %d, input: %v", i, tc.input)
   435  	}
   436  }
   437  
   438  func (s *decimalTestSuite) TestDecSortableBytes() {
   439  	tests := []struct {
   440  		d    sdk.Dec
   441  		want []byte
   442  	}{
   443  		{sdk.NewDec(0), []byte("000000000000000000.000000000000000000")},
   444  		{sdk.NewDec(1), []byte("000000000000000001.000000000000000000")},
   445  		{sdk.NewDec(10), []byte("000000000000000010.000000000000000000")},
   446  		{sdk.NewDec(12340), []byte("000000000000012340.000000000000000000")},
   447  		{sdk.NewDecWithPrec(12340, 4), []byte("000000000000000001.234000000000000000")},
   448  		{sdk.NewDecWithPrec(12340, 5), []byte("000000000000000000.123400000000000000")},
   449  		{sdk.NewDecWithPrec(12340, 8), []byte("000000000000000000.000123400000000000")},
   450  		{sdk.NewDecWithPrec(1009009009009009009, 17), []byte("000000000000000010.090090090090090090")},
   451  		{sdk.NewDecWithPrec(-1009009009009009009, 17), []byte("-000000000000000010.090090090090090090")},
   452  		{sdk.NewDec(1000000000000000000), []byte("max")},
   453  		{sdk.NewDec(-1000000000000000000), []byte("--")},
   454  	}
   455  	for tcIndex, tc := range tests {
   456  		s.Require().Equal(tc.want, sdk.SortableDecBytes(tc.d), "bad String(), index: %v", tcIndex)
   457  	}
   458  
   459  	s.Require().Panics(func() { sdk.SortableDecBytes(sdk.NewDec(1000000000000000001)) })
   460  	s.Require().Panics(func() { sdk.SortableDecBytes(sdk.NewDec(-1000000000000000001)) })
   461  }
   462  
   463  func (s *decimalTestSuite) TestDecEncoding() {
   464  	largestBigInt, ok := new(big.Int).SetString("33499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
   465  	s.Require().True(ok)
   466  
   467  	smallestBigInt, ok := new(big.Int).SetString("-33499189745056880149688856635597007162669032647290798121690100488888732861290034376435130433535", 10)
   468  	s.Require().True(ok)
   469  
   470  	const maxDecBitLen = 315
   471  	maxInt, ok := new(big.Int).SetString(strings.Repeat("1", maxDecBitLen), 2)
   472  	s.Require().True(ok)
   473  
   474  	errMaxInt, ok := new(big.Int).SetString(strings.Repeat("1", maxDecBitLen+1), 2)
   475  	s.Require().True(ok)
   476  
   477  	testCases := []struct {
   478  		input   sdk.Dec
   479  		rawBz   string
   480  		jsonStr string
   481  		yamlStr string
   482  		isErr   bool
   483  	}{
   484  		{
   485  			sdk.NewDec(0), "30",
   486  			"\"0.000000000000000000\"",
   487  			"\"0.000000000000000000\"\n",
   488  			false,
   489  		},
   490  		{
   491  			sdk.NewDecWithPrec(4, 2),
   492  			"3430303030303030303030303030303030",
   493  			"\"0.040000000000000000\"",
   494  			"\"0.040000000000000000\"\n",
   495  			false,
   496  		},
   497  		{
   498  			sdk.NewDecWithPrec(-4, 2),
   499  			"2D3430303030303030303030303030303030",
   500  			"\"-0.040000000000000000\"",
   501  			"\"-0.040000000000000000\"\n",
   502  			false,
   503  		},
   504  		{
   505  			sdk.NewDecWithPrec(1414213562373095049, 18),
   506  			"31343134323133353632333733303935303439",
   507  			"\"1.414213562373095049\"",
   508  			"\"1.414213562373095049\"\n",
   509  			false,
   510  		},
   511  		{
   512  			sdk.NewDecWithPrec(-1414213562373095049, 18),
   513  			"2D31343134323133353632333733303935303439",
   514  			"\"-1.414213562373095049\"",
   515  			"\"-1.414213562373095049\"\n",
   516  			false,
   517  		},
   518  		{
   519  			sdk.NewDecFromBigIntWithPrec(largestBigInt, 18),
   520  			"3333343939313839373435303536383830313439363838383536363335353937303037313632363639303332363437323930373938313231363930313030343838383838373332383631323930303334333736343335313330343333353335",
   521  			"\"33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"",
   522  			"\"33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"\n",
   523  			false,
   524  		},
   525  		{
   526  			sdk.NewDecFromBigIntWithPrec(smallestBigInt, 18),
   527  			"2D3333343939313839373435303536383830313439363838383536363335353937303037313632363639303332363437323930373938313231363930313030343838383838373332383631323930303334333736343335313330343333353335",
   528  			"\"-33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"",
   529  			"\"-33499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"\n",
   530  			false,
   531  		},
   532  		{
   533  			sdk.NewDecFromBigIntWithPrec(maxInt, 18),
   534  			"3636373439353934383732353238343430303734383434343238333137373938353033353831333334353136333233363435333939303630383435303530323434343434333636343330363435303137313838323137353635323136373637",
   535  			"\"66749594872528440074844428317798503581334516323645399060845050244444366430645.017188217565216767\"",
   536  			"\"66749594872528440074844428317798503581334516323645399060845050244444366430645.017188217565216767\"\n",
   537  			false,
   538  		},
   539  		{
   540  			sdk.NewDecFromBigIntWithPrec(errMaxInt, 18),
   541  			"313333343939313839373435303536383830313439363838383536363335353937303037313632363639303332363437323930373938313231363930313030343838383838373332383631323930303334333736343335313330343333353335",
   542  			"\"133499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"",
   543  			"\"133499189745056880149688856635597007162669032647290798121690100488888732861290.034376435130433535\"\n",
   544  			true,
   545  		},
   546  	}
   547  
   548  	for _, tc := range testCases {
   549  		bz, err := tc.input.Marshal()
   550  		s.Require().NoError(err)
   551  		s.Require().Equal(tc.rawBz, fmt.Sprintf("%X", bz))
   552  
   553  		var other sdk.Dec
   554  		if tc.isErr {
   555  			s.Require().Error((&other).Unmarshal(bz))
   556  		} else {
   557  			s.Require().NoError((&other).Unmarshal(bz))
   558  		}
   559  		s.Require().True(tc.input.Equal(other))
   560  
   561  		bz, err = json.Marshal(tc.input)
   562  		s.Require().NoError(err)
   563  		s.Require().Equal(tc.jsonStr, string(bz))
   564  		if tc.isErr {
   565  			s.Require().Error(json.Unmarshal(bz, &other))
   566  		} else {
   567  			s.Require().NoError(json.Unmarshal(bz, &other))
   568  		}
   569  		s.Require().True(tc.input.Equal(other))
   570  
   571  		bz, err = yaml.Marshal(tc.input)
   572  		s.Require().NoError(err)
   573  		s.Require().Equal(tc.yamlStr, string(bz))
   574  	}
   575  }
   576  
   577  // Showcase that different orders of operations causes different results.
   578  func (s *decimalTestSuite) TestOperationOrders() {
   579  	n1 := sdk.NewDec(10)
   580  	n2 := sdk.NewDec(1000000010)
   581  	s.Require().Equal(n1.Mul(n2).Quo(n2), sdk.NewDec(10))
   582  	s.Require().NotEqual(n1.Mul(n2).Quo(n2), n1.Quo(n2).Mul(n2))
   583  }
   584  
   585  func BenchmarkMarshalTo(b *testing.B) {
   586  	b.ReportAllocs()
   587  	bis := []struct {
   588  		in   sdk.Dec
   589  		want []byte
   590  	}{
   591  		{
   592  			sdk.NewDec(1e8), []byte{
   593  				0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
   594  				0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
   595  				0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
   596  			},
   597  		},
   598  		{sdk.NewDec(0), []byte{0x30}},
   599  	}
   600  	data := make([]byte, 100)
   601  
   602  	b.ReportAllocs()
   603  	b.ResetTimer()
   604  
   605  	for i := 0; i < b.N; i++ {
   606  		for _, bi := range bis {
   607  			if n, err := bi.in.MarshalTo(data); err != nil {
   608  				b.Fatal(err)
   609  			} else {
   610  				if !bytes.Equal(data[:n], bi.want) {
   611  					b.Fatalf("Mismatch\nGot:  % x\nWant: % x\n", data[:n], bi.want)
   612  				}
   613  			}
   614  		}
   615  	}
   616  }