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 }