github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/types/decimal_test.go (about)

     1  package types
     2  
     3  import (
     4  	"math"
     5  	"math/big"
     6  	"testing"
     7  
     8  	"github.com/tendermint/go-amino"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    15  )
    16  
    17  // create a decimal from a decimal string (ex. "1234.5678")
    18  func mustNewDecFromStr(t *testing.T, str string) (d Dec) {
    19  	d, err := NewDecFromStr(str)
    20  	require.NoError(t, err)
    21  	return d
    22  }
    23  
    24  //_______________________________________
    25  
    26  func TestPrecisionMultiplier(t *testing.T) {
    27  	res := precisionMultiplier(5)
    28  	exp := big.NewInt(10000000000000)
    29  	require.Equal(t, 0, res.Cmp(exp), "equality was incorrect, res %v, exp %v", res, exp)
    30  }
    31  
    32  func TestNewDecFromStr(t *testing.T) {
    33  	largeBigInt, success := new(big.Int).SetString("3144605511029693144278234343371835", 10)
    34  	require.True(t, success)
    35  	tests := []struct {
    36  		decimalStr string
    37  		expErr     bool
    38  		exp        Dec
    39  	}{
    40  		{"", true, Dec{}},
    41  		{"0.-75", true, Dec{}},
    42  		{"0", false, NewDec(0)},
    43  		{"1", false, NewDec(1)},
    44  		{"1.1", false, NewDecWithPrec(11, 1)},
    45  		{"0.75", false, NewDecWithPrec(75, 2)},
    46  		{"0.8", false, NewDecWithPrec(8, 1)},
    47  		{"0.11111", false, NewDecWithPrec(11111, 5)},
    48  		{"314460551102969.3144278234343371835", true, NewDec(3141203149163817869)},
    49  		{"314460551102969314427823434337.1835718092488231350",
    50  			true, NewDecFromBigIntWithPrec(largeBigInt, 4)},
    51  		{"314460551102969314427823434337.1835",
    52  			false, NewDecFromBigIntWithPrec(largeBigInt, 4)},
    53  		{".", true, Dec{}},
    54  		{".0", true, NewDec(0)},
    55  		{"1.", true, NewDec(1)},
    56  		{"foobar", true, Dec{}},
    57  		{"0.foobar", true, Dec{}},
    58  		{"0.foobar.", true, Dec{}},
    59  		{"88888888888888888888888888888888888888888888888888888888888888888888844444440", true, Dec{}},
    60  	}
    61  
    62  	for tcIndex, tc := range tests {
    63  		res, err := NewDecFromStr(tc.decimalStr)
    64  		if tc.expErr {
    65  			require.NotNil(t, err, "error expected, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    66  		} else {
    67  			require.Nil(t, err, "unexpected error, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    68  			require.True(t, res.Equal(tc.exp), "equality was incorrect, res %v, exp %v, tc %v", res, tc.exp, tcIndex)
    69  		}
    70  
    71  		// negative tc
    72  		res, err = NewDecFromStr("-" + tc.decimalStr)
    73  		if tc.expErr {
    74  			require.NotNil(t, err, "error expected, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    75  		} else {
    76  			require.Nil(t, err, "unexpected error, decimalStr %v, tc %v", tc.decimalStr, tcIndex)
    77  			exp := tc.exp.Mul(NewDec(-1))
    78  			require.True(t, res.Equal(exp), "equality was incorrect, res %v, exp %v, tc %v", res, exp, tcIndex)
    79  		}
    80  	}
    81  }
    82  
    83  func TestDecString(t *testing.T) {
    84  	tests := []struct {
    85  		d    Dec
    86  		want string
    87  	}{
    88  		{NewDec(0), "0.000000000000000000"},
    89  		{NewDec(1), "1.000000000000000000"},
    90  		{NewDec(10), "10.000000000000000000"},
    91  		{NewDec(12340), "12340.000000000000000000"},
    92  		{NewDecWithPrec(12340, 4), "1.234000000000000000"},
    93  		{NewDecWithPrec(12340, 5), "0.123400000000000000"},
    94  		{NewDecWithPrec(12340, 8), "0.000123400000000000"},
    95  		{NewDecWithPrec(1009009009009009009, 17), "10.090090090090090090"},
    96  	}
    97  	for tcIndex, tc := range tests {
    98  		assert.Equal(t, tc.want, tc.d.String(), "bad String(), index: %v", tcIndex)
    99  	}
   100  }
   101  
   102  func TestEqualities(t *testing.T) {
   103  	tests := []struct {
   104  		d1, d2     Dec
   105  		gt, lt, eq bool
   106  	}{
   107  		{NewDec(0), NewDec(0), false, false, true},
   108  		{NewDecWithPrec(0, 2), NewDecWithPrec(0, 4), false, false, true},
   109  		{NewDecWithPrec(100, 0), NewDecWithPrec(100, 0), false, false, true},
   110  		{NewDecWithPrec(-100, 0), NewDecWithPrec(-100, 0), false, false, true},
   111  		{NewDecWithPrec(-1, 1), NewDecWithPrec(-1, 1), false, false, true},
   112  		{NewDecWithPrec(3333, 3), NewDecWithPrec(3333, 3), false, false, true},
   113  
   114  		{NewDecWithPrec(0, 0), NewDecWithPrec(3333, 3), false, true, false},
   115  		{NewDecWithPrec(0, 0), NewDecWithPrec(100, 0), false, true, false},
   116  		{NewDecWithPrec(-1, 0), NewDecWithPrec(3333, 3), false, true, false},
   117  		{NewDecWithPrec(-1, 0), NewDecWithPrec(100, 0), false, true, false},
   118  		{NewDecWithPrec(1111, 3), NewDecWithPrec(100, 0), false, true, false},
   119  		{NewDecWithPrec(1111, 3), NewDecWithPrec(3333, 3), false, true, false},
   120  		{NewDecWithPrec(-3333, 3), NewDecWithPrec(-1111, 3), false, true, false},
   121  
   122  		{NewDecWithPrec(3333, 3), NewDecWithPrec(0, 0), true, false, false},
   123  		{NewDecWithPrec(100, 0), NewDecWithPrec(0, 0), true, false, false},
   124  		{NewDecWithPrec(3333, 3), NewDecWithPrec(-1, 0), true, false, false},
   125  		{NewDecWithPrec(100, 0), NewDecWithPrec(-1, 0), true, false, false},
   126  		{NewDecWithPrec(100, 0), NewDecWithPrec(1111, 3), true, false, false},
   127  		{NewDecWithPrec(3333, 3), NewDecWithPrec(1111, 3), true, false, false},
   128  		{NewDecWithPrec(-1111, 3), NewDecWithPrec(-3333, 3), true, false, false},
   129  	}
   130  
   131  	for tcIndex, tc := range tests {
   132  		require.Equal(t, tc.gt, tc.d1.GT(tc.d2), "GT result is incorrect, tc %d", tcIndex)
   133  		require.Equal(t, tc.lt, tc.d1.LT(tc.d2), "LT result is incorrect, tc %d", tcIndex)
   134  		require.Equal(t, tc.eq, tc.d1.Equal(tc.d2), "equality result is incorrect, tc %d", tcIndex)
   135  	}
   136  
   137  }
   138  
   139  func TestDecsEqual(t *testing.T) {
   140  	tests := []struct {
   141  		d1s, d2s []Dec
   142  		eq       bool
   143  	}{
   144  		{[]Dec{NewDec(0)}, []Dec{NewDec(0)}, true},
   145  		{[]Dec{NewDec(0)}, []Dec{NewDec(1)}, false},
   146  		{[]Dec{NewDec(0)}, []Dec{}, false},
   147  		{[]Dec{NewDec(0), NewDec(1)}, []Dec{NewDec(0), NewDec(1)}, true},
   148  		{[]Dec{NewDec(1), NewDec(0)}, []Dec{NewDec(1), NewDec(0)}, true},
   149  		{[]Dec{NewDec(1), NewDec(0)}, []Dec{NewDec(0), NewDec(1)}, false},
   150  		{[]Dec{NewDec(1), NewDec(0)}, []Dec{NewDec(1)}, false},
   151  		{[]Dec{NewDec(1), NewDec(2)}, []Dec{NewDec(2), NewDec(4)}, false},
   152  		{[]Dec{NewDec(3), NewDec(18)}, []Dec{NewDec(1), NewDec(6)}, false},
   153  	}
   154  
   155  	for tcIndex, tc := range tests {
   156  		require.Equal(t, tc.eq, DecsEqual(tc.d1s, tc.d2s), "equality of decional arrays is incorrect, tc %d", tcIndex)
   157  		require.Equal(t, tc.eq, DecsEqual(tc.d2s, tc.d1s), "equality of decional arrays is incorrect (converse), tc %d", tcIndex)
   158  	}
   159  }
   160  
   161  func TestArithmetic(t *testing.T) {
   162  	tests := []struct {
   163  		d1, d2                                Dec
   164  		expMul, expMulTruncate                Dec
   165  		expQuo, expQuoRoundUp, expQuoTruncate Dec
   166  		expAdd, expSub                        Dec
   167  	}{
   168  		//  d1         d2         MUL    MulTruncate    QUO    QUORoundUp QUOTrunctate  ADD         SUB
   169  		{NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0)},
   170  		{NewDec(1), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(1), NewDec(1)},
   171  		{NewDec(0), NewDec(1), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(1), NewDec(-1)},
   172  		{NewDec(0), NewDec(-1), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(-1), NewDec(1)},
   173  		{NewDec(-1), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(0), NewDec(-1), NewDec(-1)},
   174  
   175  		{NewDec(1), NewDec(1), NewDec(1), NewDec(1), NewDec(1), NewDec(1), NewDec(1), NewDec(2), NewDec(0)},
   176  		{NewDec(-1), NewDec(-1), NewDec(1), NewDec(1), NewDec(1), NewDec(1), NewDec(1), NewDec(-2), NewDec(0)},
   177  		{NewDec(1), NewDec(-1), NewDec(-1), NewDec(-1), NewDec(-1), NewDec(-1), NewDec(-1), NewDec(0), NewDec(2)},
   178  		{NewDec(-1), NewDec(1), NewDec(-1), NewDec(-1), NewDec(-1), NewDec(-1), NewDec(-1), NewDec(0), NewDec(-2)},
   179  
   180  		{NewDec(3), NewDec(7), NewDec(21), NewDec(21),
   181  			NewDecWithPrec(428571428571428571, 18), NewDecWithPrec(428571428571428572, 18), NewDecWithPrec(428571428571428571, 18),
   182  			NewDec(10), NewDec(-4)},
   183  		{NewDec(2), NewDec(4), NewDec(8), NewDec(8), NewDecWithPrec(5, 1), NewDecWithPrec(5, 1), NewDecWithPrec(5, 1),
   184  			NewDec(6), NewDec(-2)},
   185  
   186  		{NewDec(100), NewDec(100), NewDec(10000), NewDec(10000), NewDec(1), NewDec(1), NewDec(1), NewDec(200), NewDec(0)},
   187  
   188  		{NewDecWithPrec(15, 1), NewDecWithPrec(15, 1), NewDecWithPrec(225, 2), NewDecWithPrec(225, 2),
   189  			NewDec(1), NewDec(1), NewDec(1), NewDec(3), NewDec(0)},
   190  		{NewDecWithPrec(3333, 4), NewDecWithPrec(333, 4), NewDecWithPrec(1109889, 8), NewDecWithPrec(1109889, 8),
   191  			MustNewDecFromStr("10.009009009009009009"), MustNewDecFromStr("10.009009009009009010"), MustNewDecFromStr("10.009009009009009009"),
   192  			NewDecWithPrec(3666, 4), NewDecWithPrec(3, 1)},
   193  	}
   194  
   195  	for tcIndex, tc := range tests {
   196  		tc := tc
   197  		resAdd := tc.d1.Add(tc.d2)
   198  		resSub := tc.d1.Sub(tc.d2)
   199  		resMul := tc.d1.Mul(tc.d2)
   200  		resMulTruncate := tc.d1.MulTruncate(tc.d2)
   201  		require.True(t, tc.expAdd.Equal(resAdd), "exp %v, res %v, tc %d", tc.expAdd, resAdd, tcIndex)
   202  		require.True(t, tc.expSub.Equal(resSub), "exp %v, res %v, tc %d", tc.expSub, resSub, tcIndex)
   203  		require.True(t, tc.expMul.Equal(resMul), "exp %v, res %v, tc %d", tc.expMul, resMul, tcIndex)
   204  		require.True(t, tc.expMulTruncate.Equal(resMulTruncate), "exp %v, res %v, tc %d", tc.expMulTruncate, resMulTruncate, tcIndex)
   205  
   206  		if tc.d2.IsZero() { // panic for divide by zero
   207  			require.Panics(t, func() { tc.d1.Quo(tc.d2) })
   208  		} else {
   209  			resQuo := tc.d1.Quo(tc.d2)
   210  			require.True(t, tc.expQuo.Equal(resQuo), "exp %v, res %v, tc %d", tc.expQuo.String(), resQuo.String(), tcIndex)
   211  
   212  			resQuoRoundUp := tc.d1.QuoRoundUp(tc.d2)
   213  			require.True(t, tc.expQuoRoundUp.Equal(resQuoRoundUp), "exp %v, res %v, tc %d",
   214  				tc.expQuoRoundUp.String(), resQuoRoundUp.String(), tcIndex)
   215  
   216  			resQuoTruncate := tc.d1.QuoTruncate(tc.d2)
   217  			require.True(t, tc.expQuoTruncate.Equal(resQuoTruncate), "exp %v, res %v, tc %d",
   218  				tc.expQuoTruncate.String(), resQuoTruncate.String(), tcIndex)
   219  		}
   220  	}
   221  }
   222  
   223  func TestBankerRoundChop(t *testing.T) {
   224  	tests := []struct {
   225  		d1  Dec
   226  		exp int64
   227  	}{
   228  		{mustNewDecFromStr(t, "0.25"), 0},
   229  		{mustNewDecFromStr(t, "0"), 0},
   230  		{mustNewDecFromStr(t, "1"), 1},
   231  		{mustNewDecFromStr(t, "0.75"), 1},
   232  		{mustNewDecFromStr(t, "0.5"), 0},
   233  		{mustNewDecFromStr(t, "7.5"), 8},
   234  		{mustNewDecFromStr(t, "1.5"), 2},
   235  		{mustNewDecFromStr(t, "2.5"), 2},
   236  		{mustNewDecFromStr(t, "0.545"), 1}, // 0.545-> 1 even though 5 is first decimal and 1 not even
   237  		{mustNewDecFromStr(t, "1.545"), 2},
   238  	}
   239  
   240  	for tcIndex, tc := range tests {
   241  		resNeg := tc.d1.Neg().RoundInt64()
   242  		require.Equal(t, -1*tc.exp, resNeg, "negative tc %d", tcIndex)
   243  
   244  		resPos := tc.d1.RoundInt64()
   245  		require.Equal(t, tc.exp, resPos, "positive tc %d", tcIndex)
   246  	}
   247  }
   248  
   249  func TestTruncate(t *testing.T) {
   250  	tests := []struct {
   251  		d1  Dec
   252  		exp int64
   253  	}{
   254  		{mustNewDecFromStr(t, "0"), 0},
   255  		{mustNewDecFromStr(t, "0.25"), 0},
   256  		{mustNewDecFromStr(t, "0.75"), 0},
   257  		{mustNewDecFromStr(t, "1"), 1},
   258  		{mustNewDecFromStr(t, "1.5"), 1},
   259  		{mustNewDecFromStr(t, "7.5"), 7},
   260  		{mustNewDecFromStr(t, "7.6"), 7},
   261  		{mustNewDecFromStr(t, "7.4"), 7},
   262  		{mustNewDecFromStr(t, "100.1"), 100},
   263  		{mustNewDecFromStr(t, "1000.1"), 1000},
   264  	}
   265  
   266  	for tcIndex, tc := range tests {
   267  		resNeg := tc.d1.Neg().TruncateInt64()
   268  		require.Equal(t, -1*tc.exp, resNeg, "negative tc %d", tcIndex)
   269  
   270  		resPos := tc.d1.TruncateInt64()
   271  		require.Equal(t, tc.exp, resPos, "positive tc %d", tcIndex)
   272  	}
   273  }
   274  
   275  var cdc = codec.New()
   276  
   277  func TestDecMarshalJSON(t *testing.T) {
   278  	decimal := func(i int64) Dec {
   279  		d := NewDec(0)
   280  		d.Int = new(big.Int).SetInt64(i)
   281  		return d
   282  	}
   283  	tests := []struct {
   284  		name    string
   285  		d       Dec
   286  		want    string
   287  		wantErr bool // if wantErr = false, will also attempt unmarshaling
   288  	}{
   289  		{"zero", decimal(0), "\"0.000000000000000000\"", false},
   290  		{"one", decimal(1), "\"0.000000000000000001\"", false},
   291  		{"ten", decimal(10), "\"0.000000000000000010\"", false},
   292  		{"12340", decimal(12340), "\"0.000000000000012340\"", false},
   293  		{"zeroInt", NewDec(0), "\"0.000000000000000000\"", false},
   294  		{"oneInt", NewDec(1), "\"1.000000000000000000\"", false},
   295  		{"tenInt", NewDec(10), "\"10.000000000000000000\"", false},
   296  		{"12340Int", NewDec(12340), "\"12340.000000000000000000\"", false},
   297  	}
   298  	for _, tt := range tests {
   299  		tt := tt
   300  		t.Run(tt.name, func(t *testing.T) {
   301  			got, err := tt.d.MarshalJSON()
   302  			if (err != nil) != tt.wantErr {
   303  				t.Errorf("Dec.MarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
   304  				return
   305  			}
   306  			if !tt.wantErr {
   307  				assert.Equal(t, tt.want, string(got), "incorrect marshalled value")
   308  				unmarshalledDec := NewDec(0)
   309  				unmarshalledDec.UnmarshalJSON(got)
   310  				assert.Equal(t, tt.d, unmarshalledDec, "incorrect unmarshalled value")
   311  			}
   312  		})
   313  	}
   314  }
   315  
   316  func TestZeroDeserializationJSON(t *testing.T) {
   317  	d := Dec{new(big.Int)}
   318  	err := cdc.UnmarshalJSON([]byte(`"0"`), &d)
   319  	require.Nil(t, err)
   320  	err = cdc.UnmarshalJSON([]byte(`"{}"`), &d)
   321  	require.NotNil(t, err)
   322  }
   323  
   324  func TestSerializationText(t *testing.T) {
   325  	d := mustNewDecFromStr(t, "0.333")
   326  
   327  	bz, err := d.MarshalText()
   328  	require.NoError(t, err)
   329  
   330  	d2 := Dec{new(big.Int)}
   331  	err = d2.UnmarshalText(bz)
   332  	require.NoError(t, err)
   333  	require.True(t, d.Equal(d2), "original: %v, unmarshalled: %v", d, d2)
   334  }
   335  
   336  func TestSerializationGocodecJSON(t *testing.T) {
   337  	d := mustNewDecFromStr(t, "0.333")
   338  
   339  	bz, err := cdc.MarshalJSON(d)
   340  	require.NoError(t, err)
   341  
   342  	d2 := Dec{new(big.Int)}
   343  	err = cdc.UnmarshalJSON(bz, &d2)
   344  	require.NoError(t, err)
   345  	require.True(t, d.Equal(d2), "original: %v, unmarshalled: %v", d, d2)
   346  }
   347  
   348  func TestSerializationGocodecBinary(t *testing.T) {
   349  	d := mustNewDecFromStr(t, "0.333")
   350  
   351  	bz, err := cdc.MarshalBinaryLengthPrefixed(d)
   352  	require.NoError(t, err)
   353  
   354  	var d2 Dec
   355  	err = cdc.UnmarshalBinaryLengthPrefixed(bz, &d2)
   356  	require.NoError(t, err)
   357  	require.True(t, d.Equal(d2), "original: %v, unmarshalled: %v", d, d2)
   358  }
   359  
   360  type testDEmbedStruct struct {
   361  	Field1 string `json:"f1"`
   362  	Field2 int    `json:"f2"`
   363  	Field3 Dec    `json:"f3"`
   364  }
   365  
   366  // TODO make work for UnmarshalJSON
   367  func TestEmbeddedStructSerializationGocodec(t *testing.T) {
   368  	obj := testDEmbedStruct{"foo", 10, NewDecWithPrec(1, 3)}
   369  	bz, err := cdc.MarshalBinaryLengthPrefixed(obj)
   370  	require.Nil(t, err)
   371  
   372  	var obj2 testDEmbedStruct
   373  	err = cdc.UnmarshalBinaryLengthPrefixed(bz, &obj2)
   374  	require.Nil(t, err)
   375  
   376  	require.Equal(t, obj.Field1, obj2.Field1)
   377  	require.Equal(t, obj.Field2, obj2.Field2)
   378  	require.True(t, obj.Field3.Equal(obj2.Field3), "original: %v, unmarshalled: %v", obj, obj2)
   379  }
   380  
   381  func TestStringOverflow(t *testing.T) {
   382  	// two random 64 bit primes
   383  	dec1, err := NewDecFromStr("51643150036226787134389711697696177267")
   384  	require.NoError(t, err)
   385  	dec2, err := NewDecFromStr("-31798496660535729618459429845579852627")
   386  	require.NoError(t, err)
   387  	dec3 := dec1.Add(dec2)
   388  	require.Equal(t,
   389  		"19844653375691057515930281852116324640.000000000000000000",
   390  		dec3.String(),
   391  	)
   392  }
   393  
   394  func TestDecMulInt(t *testing.T) {
   395  	tests := []struct {
   396  		sdkDec Dec
   397  		sdkInt Int
   398  		want   Dec
   399  	}{
   400  		{NewDec(10), NewInt(2), NewDec(20)},
   401  		{NewDec(1000000), NewInt(100), NewDec(100000000)},
   402  		{NewDecWithPrec(1, 1), NewInt(10), NewDec(1)},
   403  		{NewDecWithPrec(1, 5), NewInt(20), NewDecWithPrec(2, 4)},
   404  	}
   405  	for i, tc := range tests {
   406  		got := tc.sdkDec.MulInt(tc.sdkInt)
   407  		require.Equal(t, tc.want, got, "Incorrect result on test case %d", i)
   408  	}
   409  }
   410  
   411  func TestDecCeil(t *testing.T) {
   412  	testCases := []struct {
   413  		input    Dec
   414  		expected Dec
   415  	}{
   416  		{NewDecWithPrec(1000000000000000, Precision), NewDec(1)},  // 0.001 => 1.0
   417  		{NewDecWithPrec(-1000000000000000, Precision), ZeroDec()}, // -0.001 => 0.0
   418  		{ZeroDec(), ZeroDec()}, // 0.0 => 0.0
   419  		{NewDecWithPrec(900000000000000000, Precision), NewDec(1)},    // 0.9 => 1.0
   420  		{NewDecWithPrec(4001000000000000000, Precision), NewDec(5)},   // 4.001 => 5.0
   421  		{NewDecWithPrec(-4001000000000000000, Precision), NewDec(-4)}, // -4.001 => -4.0
   422  		{NewDecWithPrec(4700000000000000000, Precision), NewDec(5)},   // 4.7 => 5.0
   423  		{NewDecWithPrec(-4700000000000000000, Precision), NewDec(-4)}, // -4.7 => -4.0
   424  	}
   425  
   426  	for i, tc := range testCases {
   427  		res := tc.input.Ceil()
   428  		require.Equal(t, tc.expected, res, "unexpected result for test case %d, input: %v", i, tc.input)
   429  	}
   430  }
   431  
   432  func TestPower(t *testing.T) {
   433  	testCases := []struct {
   434  		input    Dec
   435  		power    uint64
   436  		expected Dec
   437  	}{
   438  		{OneDec(), 10, OneDec()},                                               // 1.0 ^ (10) => 1.0
   439  		{NewDecWithPrec(5, 1), 2, NewDecWithPrec(25, 2)},                       // 0.5 ^ 2 => 0.25
   440  		{NewDecWithPrec(2, 1), 2, NewDecWithPrec(4, 2)},                        // 0.2 ^ 2 => 0.04
   441  		{NewDecFromInt(NewInt(3)), 3, NewDecFromInt(NewInt(27))},               // 3 ^ 3 => 27
   442  		{NewDecFromInt(NewInt(-3)), 4, NewDecFromInt(NewInt(81))},              // -3 ^ 4 = 81
   443  		{NewDecWithPrec(1414213562373095049, 18), 2, NewDecFromInt(NewInt(2))}, // 1.414213562373095049 ^ 2 = 2
   444  	}
   445  
   446  	for i, tc := range testCases {
   447  		res := tc.input.Power(tc.power)
   448  		require.True(t, tc.expected.Sub(res).Abs().LTE(SmallestDec()), "unexpected result for test case %d, input: %v", i, tc.input)
   449  	}
   450  }
   451  
   452  func TestApproxRoot(t *testing.T) {
   453  	testCases := []struct {
   454  		input    Dec
   455  		root     uint64
   456  		expected Dec
   457  	}{
   458  		{OneDec(), 10, OneDec()},                                                       // 1.0 ^ (0.1) => 1.0
   459  		{NewDecWithPrec(25, 2), 2, NewDecWithPrec(5, 1)},                               // 0.25 ^ (0.5) => 0.5
   460  		{NewDecWithPrec(4, 2), 2, NewDecWithPrec(2, 1)},                                // 0.04 ^ (0.5) => 0.2
   461  		{NewDecFromInt(NewInt(27)), 3, NewDecFromInt(NewInt(3))},                       // 27 ^ (1/3) => 3
   462  		{NewDecFromInt(NewInt(-81)), 4, NewDecFromInt(NewInt(-3))},                     // -81 ^ (0.25) => -3
   463  		{NewDecFromInt(NewInt(2)), 2, NewDecWithPrec(1414213562373095049, 18)},         // 2 ^ (0.5) => 1.414213562373095049
   464  		{NewDecWithPrec(1005, 3), 31536000, MustNewDecFromStr("1.000000000158153904")}, // 1.005 ^ (1/31536000) ≈ 1.00000000016
   465  		{SmallestDec(), 2, NewDecWithPrec(1, 9)},                                       // 1e-18 ^ (0.5) => 1e-9
   466  		{SmallestDec(), 3, MustNewDecFromStr("0.000000999999999997")},                  // 1e-18 ^ (1/3) => 1e-6
   467  		{NewDecWithPrec(1, 8), 3, MustNewDecFromStr("0.002154434690031900")},           // 1e-8 ^ (1/3) ≈ 0.00215443469
   468  	}
   469  
   470  	// In the case of 1e-8 ^ (1/3), the result repeats every 5 iterations starting from iteration 24
   471  	// (i.e. 24, 29, 34, ... give the same result) and never converges enough. The maximum number of
   472  	// iterations (100) causes the result at iteration 100 to be returned, regardless of convergence.
   473  
   474  	for i, tc := range testCases {
   475  		res, err := tc.input.ApproxRoot(tc.root)
   476  		require.NoError(t, err)
   477  		require.True(t, tc.expected.Sub(res).Abs().LTE(SmallestDec()), "unexpected result for test case %d, input: %v", i, tc.input)
   478  	}
   479  }
   480  
   481  func TestApproxSqrt(t *testing.T) {
   482  	testCases := []struct {
   483  		input    Dec
   484  		expected Dec
   485  	}{
   486  		{OneDec(), OneDec()},                                                // 1.0 => 1.0
   487  		{NewDecWithPrec(25, 2), NewDecWithPrec(5, 1)},                       // 0.25 => 0.5
   488  		{NewDecWithPrec(4, 2), NewDecWithPrec(2, 1)},                        // 0.09 => 0.3
   489  		{NewDecFromInt(NewInt(9)), NewDecFromInt(NewInt(3))},                // 9 => 3
   490  		{NewDecFromInt(NewInt(-9)), NewDecFromInt(NewInt(-3))},              // -9 => -3
   491  		{NewDecFromInt(NewInt(2)), NewDecWithPrec(1414213562373095049, 18)}, // 2 => 1.414213562373095049
   492  	}
   493  
   494  	for i, tc := range testCases {
   495  		res, err := tc.input.ApproxSqrt()
   496  		require.NoError(t, err)
   497  		require.Equal(t, tc.expected, res, "unexpected result for test case %d, input: %v", i, tc.input)
   498  	}
   499  }
   500  
   501  func TestDecSortableBytes(t *testing.T) {
   502  	tests := []struct {
   503  		d    Dec
   504  		want []byte
   505  	}{
   506  		{NewDec(0), []byte("000000000000000000.000000000000000000")},
   507  		{NewDec(1), []byte("000000000000000001.000000000000000000")},
   508  		{NewDec(10), []byte("000000000000000010.000000000000000000")},
   509  		{NewDec(12340), []byte("000000000000012340.000000000000000000")},
   510  		{NewDecWithPrec(12340, 4), []byte("000000000000000001.234000000000000000")},
   511  		{NewDecWithPrec(12340, 5), []byte("000000000000000000.123400000000000000")},
   512  		{NewDecWithPrec(12340, 8), []byte("000000000000000000.000123400000000000")},
   513  		{NewDecWithPrec(1009009009009009009, 17), []byte("000000000000000010.090090090090090090")},
   514  		{NewDecWithPrec(-1009009009009009009, 17), []byte("-000000000000000010.090090090090090090")},
   515  		{NewDec(1000000000000000000), []byte("max")},
   516  		{NewDec(-1000000000000000000), []byte("--")},
   517  	}
   518  	for tcIndex, tc := range tests {
   519  		assert.Equal(t, tc.want, SortableDecBytes(tc.d), "bad String(), index: %v", tcIndex)
   520  	}
   521  
   522  	assert.Panics(t, func() { SortableDecBytes(NewDec(1000000000000000001)) })
   523  	assert.Panics(t, func() { SortableDecBytes(NewDec(-1000000000000000001)) })
   524  }
   525  
   526  func TestDecAmino(t *testing.T) {
   527  	testCases := []Dec{
   528  		{},
   529  		{big.NewInt(0)},
   530  		{new(big.Int)},
   531  		{big.NewInt(12345)},
   532  		{big.NewInt(math.MaxInt64)},
   533  		{big.NewInt(math.MinInt64)},
   534  		{big.NewInt(0).Mul(big.NewInt(math.MaxInt64), big.NewInt(math.MaxInt64))},
   535  	}
   536  	cdc := amino.NewCodec()
   537  	for _, dec := range testCases {
   538  		expectData, err := cdc.MarshalBinaryBare(dec)
   539  		require.NoError(t, err)
   540  
   541  		actualData, err := dec.MarshalToAmino(cdc)
   542  		require.NoError(t, err)
   543  
   544  		bareData, err := amino.GetBinaryBareFromBinaryLengthPrefixed(expectData)
   545  		require.NoError(t, err)
   546  		require.EqualValues(t, bareData, actualData)
   547  
   548  		require.Equal(t, len(bareData), dec.AminoSize(cdc))
   549  
   550  		var expectValue Dec
   551  		err = cdc.UnmarshalBinaryBare(expectData, &expectValue)
   552  		require.NoError(t, err)
   553  
   554  		actualValue := Dec{}
   555  		err = actualValue.UnmarshalFromAmino(cdc, bareData)
   556  		require.NoError(t, err)
   557  
   558  		require.EqualValues(t, expectValue, actualValue)
   559  	}
   560  }