github.com/dubbogo/gost@v1.14.0/math/big/decimal_test.go (about) 1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package gxbig 19 20 import ( 21 "fmt" 22 "strconv" 23 "strings" 24 "testing" 25 ) 26 27 import ( 28 "github.com/stretchr/testify/require" 29 ) 30 31 func TestFromInt(t *testing.T) { 32 tests := []struct { 33 input int64 34 output string 35 }{ 36 {-12345, "-12345"}, 37 {-1, "-1"}, 38 {1, "1"}, 39 {-9223372036854775807, "-9223372036854775807"}, 40 {-9223372036854775808, "-9223372036854775808"}, 41 } 42 for _, tt := range tests { 43 dec := NewDecFromInt(tt.input) 44 str := dec.ToString() 45 require.Equal(t, tt.output, string(str)) 46 } 47 } 48 49 func TestFromUint(t *testing.T) { 50 tests := []struct { 51 input uint64 52 output string 53 }{ 54 {12345, "12345"}, 55 {0, "0"}, 56 {18446744073709551615, "18446744073709551615"}, 57 } 58 for _, tt := range tests { 59 var dec Decimal 60 dec.FromUint(tt.input) 61 str := dec.ToString() 62 require.Equal(t, tt.output, string(str)) 63 } 64 } 65 66 func TestToInt(t *testing.T) { 67 tests := []struct { 68 input string 69 output int64 70 err error 71 }{ 72 {"18446744073709551615", 9223372036854775807, ErrOverflow}, 73 {"-1", -1, nil}, 74 {"1", 1, nil}, 75 {"-1.23", -1, ErrTruncated}, 76 {"-9223372036854775807", -9223372036854775807, nil}, 77 {"-9223372036854775808", -9223372036854775808, nil}, 78 {"9223372036854775808", 9223372036854775807, ErrOverflow}, 79 {"-9223372036854775809", -9223372036854775808, ErrOverflow}, 80 } 81 for _, tt := range tests { 82 var dec Decimal 83 err := dec.FromString(tt.input) 84 require.NoError(t, err) 85 result, ec := dec.ToInt() 86 require.Equal(t, tt.err, ec) 87 require.Equal(t, tt.output, result) 88 } 89 } 90 91 func TestToUint(t *testing.T) { 92 tests := []struct { 93 input string 94 output uint64 95 err error 96 }{ 97 {"12345", 12345, nil}, 98 {"0", 0, nil}, 99 /* ULLONG_MAX = 18446744073709551615ULL */ 100 {"18446744073709551615", 18446744073709551615, nil}, 101 {"18446744073709551616", 18446744073709551615, ErrOverflow}, 102 {"-1", 0, ErrOverflow}, 103 {"1.23", 1, ErrTruncated}, 104 {"9999999999999999999999999.000", 18446744073709551615, ErrOverflow}, 105 } 106 for _, tt := range tests { 107 var dec Decimal 108 err := dec.FromString(tt.input) 109 require.NoError(t, err) 110 result, ec := dec.ToUint() 111 require.Equal(t, tt.err, ec) 112 require.Equal(t, tt.output, result) 113 } 114 } 115 116 func TestFromFloat(t *testing.T) { 117 tests := []struct { 118 s string 119 f float64 120 }{ 121 {"12345", 12345}, 122 {"123.45", 123.45}, 123 {"-123.45", -123.45}, 124 {"0.00012345000098765", 0.00012345000098765}, 125 {"1234500009876.5", 1234500009876.5}, 126 } 127 for _, tt := range tests { 128 dec, err := NewDecFromFloat(tt.f) 129 str := dec.ToString() 130 require.Equal(t, err, nil) 131 require.Equal(t, tt.s, string(str)) 132 } 133 } 134 135 func TestToFloat(t *testing.T) { 136 tests := []struct { 137 in string 138 out string 139 err error 140 }{ 141 {"12345", "12345", nil}, 142 {"123.45", "123.45", nil}, 143 {"-123.45", "-123.45", nil}, 144 {"0.00012345000098765", "0.00012345000098765", nil}, 145 {"1234500009876.5", "1234500009876.5", nil}, 146 {"1e39", "1e39", nil}, 147 {"1e-39", "1e-39", nil}, 148 {"1e00", "1", nil}, 149 {"1e001", "10", nil}, 150 {"-9223372036854775807", "-9223372036854775807", nil}, 151 {"-9223372036854775808", "-9223372036854775808", nil}, 152 {"18446744073709551615", "18446744073709551615", nil}, 153 {"123456789.987654321", "123456789.987654321", nil}, 154 // Testcases from https://github.com/golang/go/blob/master/src/strconv/atof_test.go#L24 155 {"1", "1", nil}, 156 {"+1", "1", nil}, 157 {"1e23", "1e+23", nil}, 158 {"1E23", "1e+23", nil}, 159 {"100000000000000000000000", "1e+23", nil}, 160 {"123456700", "1.234567e+08", nil}, 161 {"99999999999999974834176", "9.999999999999997e+22", nil}, 162 {"100000000000000000000001", "1.0000000000000001e+23", nil}, 163 {"100000000000000008388608", "1.0000000000000001e+23", nil}, 164 {"100000000000000016777215", "1.0000000000000001e+23", nil}, 165 {"100000000000000016777216", "1.0000000000000003e+23", nil}, 166 {"-1", "-1", nil}, 167 {"-0.1", "-0.1", nil}, 168 {"-0", "-0", nil}, 169 {"1e-20", "1e-20", nil}, 170 {"625e-3", "0.625", nil}, 171 {"0", "0", nil}, 172 {"22.222222222222222", "22.22222222222222", nil}, 173 {"1.00000000000000011102230246251565404236316680908203125", "1", nil}, 174 {"1.00000000000000011102230246251565404236316680908203124", "1", nil}, 175 {"1.00000000000000011102230246251565404236316680908203126", "1.0000000000000002", nil}, 176 {"1.00000000000000033306690738754696212708950042724609375", "1.0000000000000004", nil}, 177 {"1090544144181609348671888949248", "1.0905441441816093e+30", nil}, 178 {"1090544144181609348835077142190", "1.0905441441816094e+30", nil}, 179 } 180 for _, ca := range tests { 181 var dec Decimal 182 err := dec.FromString(ca.in) 183 require.NoError(t, err) 184 f, err := dec.ToFloat64() 185 require.NoError(t, err) 186 std, err := strconv.ParseFloat(ca.out, 64) 187 require.NoError(t, err) 188 require.Equal(t, std, f) 189 } 190 } 191 192 func TestToHashKey(t *testing.T) { 193 tests := []struct { 194 numbers []string 195 }{ 196 {[]string{"1.1", "1.1000", "1.1000000", "1.10000000000", "01.1", "0001.1", "001.1000000"}}, 197 {[]string{"-1.1", "-1.1000", "-1.1000000", "-1.10000000000", "-01.1", "-0001.1", "-001.1000000"}}, 198 {[]string{".1", "0.1", "0.10", "000000.1", ".10000", "0000.10000", "000000000000000000.1"}}, 199 {[]string{"0", "0000", ".0", ".00000", "00000.00000", "-0", "-0000", "-.0", "-.00000", "-00000.00000"}}, 200 {[]string{".123456789123456789", ".1234567891234567890", ".12345678912345678900", ".123456789123456789000", ".1234567891234567890000", "0.123456789123456789", 201 ".1234567891234567890000000000", "0000000.123456789123456789000"}}, 202 {[]string{"12345", "012345", "0012345", "0000012345", "0000000012345", "00000000000012345", "12345.", "12345.00", "12345.000000000", "000012345.0000"}}, 203 {[]string{"123E5", "12300000", "00123E5", "000000123E5", "12300000.00000000"}}, 204 {[]string{"123E-2", "1.23", "00000001.23", "1.2300000000000000", "000000001.23000000000000"}}, 205 } 206 for _, ca := range tests { 207 keys := make([]string, 0, len(ca.numbers)) 208 for _, num := range ca.numbers { 209 var dec Decimal 210 require.NoError(t, dec.FromString(num)) 211 key, err := dec.ToHashKey() 212 require.NoError(t, err) 213 keys = append(keys, string(key)) 214 } 215 216 for i := 1; i < len(keys); i++ { 217 require.Equal(t, keys[0], keys[i]) 218 } 219 } 220 221 binTests := []struct { 222 hashNumbers []string 223 binNumbers []string 224 }{ 225 {[]string{"1.1", "1.1000", "1.1000000", "1.10000000000", "01.1", "0001.1", "001.1000000"}, 226 []string{"1.1", "0001.1", "01.1"}}, 227 {[]string{"-1.1", "-1.1000", "-1.1000000", "-1.10000000000", "-01.1", "-0001.1", "-001.1000000"}, 228 []string{"-1.1", "-0001.1", "-01.1"}}, 229 {[]string{".1", "0.1", "000000.1", ".10000", "0000.10000", "000000000000000000.1"}, 230 []string{".1", "0.1", "000000.1", "00.1"}}, 231 {[]string{"0", "0000", ".0", ".00000", "00000.00000", "-0", "-0000", "-.0", "-.00000", "-00000.00000"}, 232 []string{"0", "0000", "00", "-0", "-00", "-000000"}}, 233 {[]string{".123456789123456789", ".1234567891234567890", ".12345678912345678900", ".123456789123456789000", ".1234567891234567890000", "0.123456789123456789", 234 ".1234567891234567890000000000", "0000000.123456789123456789000"}, 235 []string{".123456789123456789", "0.123456789123456789", "0000.123456789123456789", "0000000.123456789123456789"}}, 236 {[]string{"12345", "012345", "0012345", "0000012345", "0000000012345", "00000000000012345", "12345.", "12345.00", "12345.000000000", "000012345.0000"}, 237 []string{"12345", "012345", "000012345", "000000000000012345"}}, 238 {[]string{"123E5", "12300000", "00123E5", "000000123E5", "12300000.00000000"}, 239 []string{"12300000", "123E5", "00123E5", "0000000000123E5"}}, 240 {[]string{"123E-2", "1.23", "00000001.23", "1.2300000000000000", "000000001.23000000000000"}, 241 []string{"123E-2", "1.23", "000001.23", "0000000000001.23"}}, 242 } 243 for _, ca := range binTests { 244 keys := make([]string, 0, len(ca.hashNumbers)+len(ca.binNumbers)) 245 for _, num := range ca.hashNumbers { 246 var dec Decimal 247 require.NoError(t, dec.FromString(num)) 248 key, err := dec.ToHashKey() 249 // remove digit len 250 key = key[:len(key)-1] 251 require.NoError(t, err) 252 keys = append(keys, string(key)) 253 } 254 for _, num := range ca.binNumbers { 255 var dec Decimal 256 require.NoError(t, dec.FromString(num)) 257 prec, frac := dec.PrecisionAndFrac() // remove leading zeros but trailing zeros remain 258 key, err := dec.ToBin(prec, frac) 259 require.NoError(t, err) 260 keys = append(keys, string(key)) 261 } 262 263 for i := 1; i < len(keys); i++ { 264 require.Equal(t, keys[0], keys[i]) 265 } 266 } 267 } 268 269 func TestRemoveTrailingZeros(t *testing.T) { 270 tests := []string{ 271 "0", "0.0", ".0", ".00000000", "0.0000", "0000", "0000.0", "0000.000", 272 "-0", "-0.0", "-.0", "-.00000000", "-0.0000", "-0000", "-0000.0", "-0000.000", 273 "123123123", "213123.", "21312.000", "21321.123", "213.1230000", "213123.000123000", 274 "-123123123", "-213123.", "-21312.000", "-21321.123", "-213.1230000", "-213123.000123000", 275 "123E5", "12300E-5", "0.00100E1", "0.001230E-3", 276 "123987654321.123456789000", "000000000123", "123456789.987654321", "999.999000", 277 } 278 for _, ca := range tests { 279 var dec Decimal 280 require.NoError(t, dec.FromString(ca)) 281 282 // calculate the number of digits after point but trailing zero 283 digitsFracExp := 0 284 str := string(dec.ToString()) 285 point := strings.Index(str, ".") 286 if point != -1 { 287 pos := len(str) - 1 288 for pos > point { 289 if str[pos] != '0' { 290 break 291 } 292 pos-- 293 } 294 digitsFracExp = pos - point 295 } 296 297 _, digitsFrac := dec.removeTrailingZeros() 298 require.Equal(t, digitsFracExp, digitsFrac) 299 } 300 } 301 302 func TestRoundWithHalfEven(t *testing.T) { 303 tests := []struct { 304 input string 305 scale int 306 output string 307 err error 308 }{ 309 {"123456789.987654321", 1, "123456790.0", nil}, 310 {"15.1", 0, "15", nil}, 311 {"15.5", 0, "16", nil}, 312 {"15.9", 0, "16", nil}, 313 {"-15.1", 0, "-15", nil}, 314 {"-15.5", 0, "-16", nil}, 315 {"-15.9", 0, "-16", nil}, 316 {"15.1", 1, "15.1", nil}, 317 {"-15.1", 1, "-15.1", nil}, 318 {"15.17", 1, "15.2", nil}, 319 {"15.4", -1, "20", nil}, 320 {"-15.4", -1, "-20", nil}, 321 {"5.4", -1, "10", nil}, 322 {".999", 0, "1", nil}, 323 {"999999999", -9, "1000000000", nil}, 324 } 325 326 for _, ca := range tests { 327 var dec Decimal 328 err := dec.FromString(ca.input) 329 require.NoError(t, err) 330 var rounded Decimal 331 err = dec.Round(&rounded, ca.scale, ModeHalfEven) 332 require.Equal(t, ca.err, err) 333 result := rounded.ToString() 334 require.Equal(t, ca.output, string(result)) 335 } 336 } 337 338 func TestRoundWithTruncate(t *testing.T) { 339 tests := []struct { 340 input string 341 scale int 342 output string 343 err error 344 }{ 345 {"123456789.987654321", 1, "123456789.9", nil}, 346 {"15.1", 0, "15", nil}, 347 {"15.5", 0, "15", nil}, 348 {"15.9", 0, "15", nil}, 349 {"-15.1", 0, "-15", nil}, 350 {"-15.5", 0, "-15", nil}, 351 {"-15.9", 0, "-15", nil}, 352 {"15.1", 1, "15.1", nil}, 353 {"-15.1", 1, "-15.1", nil}, 354 {"15.17", 1, "15.1", nil}, 355 {"15.4", -1, "10", nil}, 356 {"-15.4", -1, "-10", nil}, 357 {"5.4", -1, "0", nil}, 358 {".999", 0, "0", nil}, 359 {"999999999", -9, "0", nil}, 360 } 361 for _, ca := range tests { 362 var dec Decimal 363 err := dec.FromString(ca.input) 364 require.NoError(t, err) 365 var rounded Decimal 366 err = dec.Round(&rounded, ca.scale, ModeTruncate) 367 require.Equal(t, ca.err, err) 368 result := rounded.ToString() 369 require.Equal(t, ca.output, string(result)) 370 } 371 } 372 373 func TestRoundWithCeil(t *testing.T) { 374 tests := []struct { 375 input string 376 scale int 377 output string 378 err error 379 }{ 380 {"123456789.987654321", 1, "123456790.0", nil}, 381 {"15.1", 0, "16", nil}, 382 {"15.5", 0, "16", nil}, 383 {"15.9", 0, "16", nil}, 384 //TODO:fix me 385 {"-15.1", 0, "-16", nil}, 386 {"-15.5", 0, "-16", nil}, 387 {"-15.9", 0, "-16", nil}, 388 {"15.1", 1, "15.1", nil}, 389 {"-15.1", 1, "-15.1", nil}, 390 {"15.17", 1, "15.2", nil}, 391 {"15.4", -1, "20", nil}, 392 {"-15.4", -1, "-20", nil}, 393 {"5.4", -1, "10", nil}, 394 {".999", 0, "1", nil}, 395 {"999999999", -9, "1000000000", nil}, 396 } 397 for _, ca := range tests { 398 var dec Decimal 399 err := dec.FromString(ca.input) 400 require.NoError(t, err) 401 var rounded Decimal 402 err = dec.Round(&rounded, ca.scale, modeCeiling) 403 require.Equal(t, ca.err, err) 404 result := rounded.ToString() 405 require.Equal(t, ca.output, string(result)) 406 } 407 } 408 409 func TestToString(t *testing.T) { 410 type tcase struct { 411 input string 412 output string 413 } 414 tests := []tcase{ 415 {"123.123", "123.123"}, 416 {"123.1230", "123.1230"}, 417 {"00123.123", "123.123"}, 418 } 419 for _, ca := range tests { 420 var dec Decimal 421 err := dec.FromString(ca.input) 422 require.NoError(t, err) 423 result := dec.ToString() 424 require.Equal(t, ca.output, string(result)) 425 } 426 } 427 428 func TestToBinFromBin(t *testing.T) { 429 type tcase struct { 430 input string 431 precision int 432 frac int 433 output string 434 err error 435 } 436 tests := []tcase{ 437 {"-10.55", 4, 2, "-10.55", nil}, 438 {"0.0123456789012345678912345", 30, 25, "0.0123456789012345678912345", nil}, 439 {"12345", 5, 0, "12345", nil}, 440 {"12345", 10, 3, "12345.000", nil}, 441 {"123.45", 10, 3, "123.450", nil}, 442 {"-123.45", 20, 10, "-123.4500000000", nil}, 443 {".00012345000098765", 15, 14, "0.00012345000098", ErrTruncated}, 444 {".00012345000098765", 22, 20, "0.00012345000098765000", nil}, 445 {".12345000098765", 30, 20, "0.12345000098765000000", nil}, 446 {"-.000000012345000098765", 30, 20, "-0.00000001234500009876", ErrTruncated}, 447 {"1234500009876.5", 30, 5, "1234500009876.50000", nil}, 448 {"111111111.11", 10, 2, "11111111.11", ErrOverflow}, 449 {"000000000.01", 7, 3, "0.010", nil}, 450 {"123.4", 10, 2, "123.40", nil}, 451 {"1000", 3, 0, "0", ErrOverflow}, 452 {"0.1", 1, 1, "0.1", nil}, 453 {"0.100", 1, 1, "0.1", ErrTruncated}, 454 {"0.1000", 1, 1, "0.1", ErrTruncated}, 455 {"0.10000", 1, 1, "0.1", ErrTruncated}, 456 {"0.100000", 1, 1, "0.1", ErrTruncated}, 457 {"0.1000000", 1, 1, "0.1", ErrTruncated}, 458 {"0.10", 1, 1, "0.1", ErrTruncated}, 459 {"0000000000000000000000000000000000000000000.000000000000123000000000000000", 15, 15, "0.000000000000123", ErrTruncated}, 460 {"00000000000000000000000000000.00000000000012300", 15, 15, "0.000000000000123", ErrTruncated}, 461 {"0000000000000000000000000000000000000000000.0000000000001234000000000000000", 16, 16, "0.0000000000001234", ErrTruncated}, 462 {"00000000000000000000000000000.000000000000123400", 16, 16, "0.0000000000001234", ErrTruncated}, 463 {"0.1", 2, 2, "0.10", nil}, 464 {"0.10", 3, 3, "0.100", nil}, 465 {"0.1", 3, 1, "0.1", nil}, 466 {"0.0000000000001234", 32, 17, "0.00000000000012340", nil}, 467 {"0.0000000000001234", 20, 20, "0.00000000000012340000", nil}, 468 } 469 for _, ca := range tests { 470 var dec Decimal 471 err := dec.FromString(ca.input) 472 require.NoError(t, err) 473 buf, err := dec.ToBin(ca.precision, ca.frac) 474 require.Equal(t, ca.err, err) 475 var dec2 Decimal 476 _, err = dec2.FromBin(buf, ca.precision, ca.frac) 477 require.NoError(t, err) 478 str := dec2.ToString() 479 require.Equal(t, ca.output, string(str)) 480 } 481 var dec Decimal 482 dec.FromInt(1) 483 errTests := []struct { 484 prec int 485 frac int 486 }{ 487 {82, 1}, 488 {-1, 1}, 489 {10, 31}, 490 {10, -1}, 491 } 492 for _, tt := range errTests { 493 _, _ = dec.ToBin(tt.prec, tt.frac) 494 // assert.Equal(t,ErrBadNumber.Equal(err), IsTrue) 495 } 496 } 497 498 func TestCompareMyDecimal(t *testing.T) { 499 type tcase struct { 500 a string 501 b string 502 cmp int 503 } 504 tests := []tcase{ 505 {"12", "13", -1}, 506 {"13", "12", 1}, 507 {"-10", "10", -1}, 508 {"10", "-10", 1}, 509 {"-12", "-13", 1}, 510 {"0", "12", -1}, 511 {"-10", "0", -1}, 512 {"4", "4", 0}, 513 {"-1.1", "-1.2", 1}, 514 {"1.2", "1.1", 1}, 515 {"1.1", "1.2", -1}, 516 } 517 for _, tt := range tests { 518 var a, b Decimal 519 err := a.FromString(tt.a) 520 require.NoError(t, err) 521 err = b.FromString(tt.b) 522 require.NoError(t, err) 523 require.Equal(t, tt.cmp, a.Compare(&b)) 524 } 525 } 526 527 func TestMaxDecimal(t *testing.T) { 528 type tcase struct { 529 prec int 530 frac int 531 result string 532 } 533 tests := []tcase{ 534 {1, 1, "0.9"}, 535 {1, 0, "9"}, 536 {2, 1, "9.9"}, 537 {4, 2, "99.99"}, 538 {6, 3, "999.999"}, 539 {8, 4, "9999.9999"}, 540 {10, 5, "99999.99999"}, 541 {12, 6, "999999.999999"}, 542 {14, 7, "9999999.9999999"}, 543 {16, 8, "99999999.99999999"}, 544 {18, 9, "999999999.999999999"}, 545 {20, 10, "9999999999.9999999999"}, 546 {20, 20, "0.99999999999999999999"}, 547 {20, 0, "99999999999999999999"}, 548 {40, 20, "99999999999999999999.99999999999999999999"}, 549 } 550 for _, tt := range tests { 551 var dec Decimal 552 maxDecimal(tt.prec, tt.frac, &dec) 553 str := dec.ToString() 554 require.Equal(t, tt.result, string(str)) 555 } 556 } 557 558 func TestNegMyDecimal(t *testing.T) { 559 type testCase struct { 560 a string 561 result string 562 } 563 tests := []testCase{ 564 {"-0.0000000000000000000000000000000000000000000000000017382578996420603", "0.0000000000000000000000000000000000000000000000000017382578996420603"}, 565 {"-13890436710184412000000000000000000000000000000000000000000000000000000000000", "13890436710184412000000000000000000000000000000000000000000000000000000000000"}, 566 {"0", "0"}, 567 } 568 for _, tt := range tests { 569 a, err := NewDecFromString(tt.a) 570 negResult := DecimalNeg(a) 571 result := negResult.ToString() 572 require.Equal(t, err, nil) 573 require.Equal(t, tt.result, string(result)) 574 } 575 } 576 577 func TestAddMyDecimal(t *testing.T) { 578 type testCase struct { 579 a string 580 b string 581 result string 582 err error 583 } 584 tests := []testCase{ 585 {".00012345000098765", "123.45", "123.45012345000098765", nil}, 586 {".1", ".45", "0.55", nil}, 587 {"1234500009876.5", ".00012345000098765", "1234500009876.50012345000098765", nil}, 588 {"9999909999999.5", ".555", "9999910000000.055", nil}, 589 {"99999999", "1", "100000000", nil}, 590 {"989999999", "1", "990000000", nil}, 591 {"999999999", "1", "1000000000", nil}, 592 {"12345", "123.45", "12468.45", nil}, 593 {"-12345", "-123.45", "-12468.45", nil}, 594 {"-12345", "123.45", "-12221.55", nil}, 595 {"12345", "-123.45", "12221.55", nil}, 596 {"123.45", "-12345", "-12221.55", nil}, 597 {"-123.45", "12345", "12221.55", nil}, 598 {"5", "-6.0", "-1.0", nil}, 599 {"2" + strings.Repeat("1", 71), strings.Repeat("8", 81), "8888888890" + strings.Repeat("9", 71), nil}, 600 {"-1234.1234", "1234.1234", "0.0000", nil}, 601 } 602 for _, tt := range tests { 603 a, err1 := NewDecFromString(tt.a) 604 b, err2 := NewDecFromString(tt.b) 605 require.Equal(t, err1, nil) 606 require.Equal(t, err2, nil) 607 var sum Decimal 608 err := DecimalAdd(a, b, &sum) 609 require.Equal(t, tt.err, err) 610 result := sum.ToString() 611 require.Equal(t, tt.result, string(result)) 612 } 613 } 614 615 func TestSubMyDecimal(t *testing.T) { 616 type tcase struct { 617 a string 618 b string 619 result string 620 err error 621 } 622 tests := []tcase{ 623 {".00012345000098765", "123.45", "-123.44987654999901235", nil}, 624 {"1234500009876.5", ".00012345000098765", "1234500009876.49987654999901235", nil}, 625 {"9999900000000.5", ".555", "9999899999999.945", nil}, 626 {"1111.5551", "1111.555", "0.0001", nil}, 627 {".555", ".555", "0.000", nil}, 628 {"10000000", "1", "9999999", nil}, 629 {"1000001000", ".1", "1000000999.9", nil}, 630 {"1000000000", ".1", "999999999.9", nil}, 631 {"12345", "123.45", "12221.55", nil}, 632 {"-12345", "-123.45", "-12221.55", nil}, 633 {"123.45", "12345", "-12221.55", nil}, 634 {"-123.45", "-12345", "12221.55", nil}, 635 {"-12345", "123.45", "-12468.45", nil}, 636 {"12345", "-123.45", "12468.45", nil}, 637 {"12.12", "12.12", "0.00", nil}, 638 } 639 for _, tt := range tests { 640 var a, b, sum Decimal 641 err := a.FromString(tt.a) 642 require.NoError(t, err) 643 err = b.FromString(tt.b) 644 require.NoError(t, err) 645 err = DecimalSub(&a, &b, &sum) 646 require.Equal(t, tt.err, err) 647 result := sum.ToString() 648 require.Equal(t, tt.result, string(result)) 649 } 650 } 651 652 func TestMulMyDecimal(t *testing.T) { 653 type tcase struct { 654 a string 655 b string 656 result string 657 err error 658 } 659 tests := []tcase{ 660 {"12", "10", "120", nil}, 661 {"-123.456", "98765.4321", "-12193185.1853376", nil}, 662 {"-123456000000", "98765432100000", "-12193185185337600000000000", nil}, 663 {"123456", "987654321", "121931851853376", nil}, 664 {"123456", "9876543210", "1219318518533760", nil}, 665 {"123", "0.01", "1.23", nil}, 666 {"123", "0", "0", nil}, 667 {"-0.0000000000000000000000000000000000000000000000000017382578996420603", "-13890436710184412000000000000000000000000000000000000000000000000000000000000", "0.000000000000000000000000000000", ErrTruncated}, 668 {"1" + strings.Repeat("0", 60), "1" + strings.Repeat("0", 60), "0", ErrOverflow}, 669 {"0.5999991229316", "0.918755041726043", "0.5512522192246113614062276588", nil}, 670 {"0.5999991229317", "0.918755041726042", "0.5512522192247026369112773314", nil}, 671 {"0.000", "-1", "0.000", nil}, 672 } 673 for _, tt := range tests { 674 var a, b, product Decimal 675 err := a.FromString(tt.a) 676 require.NoError(t, err) 677 err = b.FromString(tt.b) 678 require.NoError(t, err) 679 err = DecimalMul(&a, &b, &product) 680 require.Equal(t, tt.err, err) 681 result := product.String() 682 require.Equal(t, tt.result, result) 683 } 684 } 685 686 func TestDivModMyDecimal(t *testing.T) { 687 type tcase struct { 688 a string 689 b string 690 result string 691 err error 692 } 693 tests := []tcase{ 694 {"120", "10", "12.000000000", nil}, 695 {"123", "0.01", "12300.000000000", nil}, 696 {"120", "100000000000.00000", "0.000000001200000000", nil}, 697 {"123", "0", "", ErrDivByZero}, 698 {"0", "0", "", ErrDivByZero}, 699 {"-12193185.1853376", "98765.4321", "-123.456000000000000000", nil}, 700 {"121931851853376", "987654321", "123456.000000000", nil}, 701 {"0", "987", "0.00000", nil}, 702 {"1", "3", "0.333333333", nil}, 703 {"1.000000000000", "3", "0.333333333333333333", nil}, 704 {"1", "1", "1.000000000", nil}, 705 {"0.0123456789012345678912345", "9999999999", "0.000000000001234567890246913578148141", nil}, 706 {"10.333000000", "12.34500", "0.837019036046982584042122316", nil}, 707 {"10.000000000060", "2", "5.000000000030000000", nil}, 708 {"51", "0.003430", "14868.804664723032069970", nil}, 709 } 710 for _, tt := range tests { 711 var a, b, to Decimal 712 err := a.FromString(tt.a) 713 require.NoError(t, err) 714 err = b.FromString(tt.b) 715 require.NoError(t, err) 716 err = DecimalDiv(&a, &b, &to, 5) 717 require.Equal(t, tt.err, err) 718 if tt.err == ErrDivByZero { 719 continue 720 } 721 result := to.ToString() 722 require.Equal(t, tt.result, string(result)) 723 } 724 725 tests = []tcase{ 726 {"234", "10", "4", nil}, 727 {"234.567", "10.555", "2.357", nil}, 728 {"-234.567", "10.555", "-2.357", nil}, 729 {"234.567", "-10.555", "2.357", nil}, 730 {"99999999999999999999999999999999999999", "3", "0", nil}, 731 {"51", "0.003430", "0.002760", nil}, 732 {"0.0000000001", "1.0", "0.0000000001", nil}, 733 {"0.000", "0.1", "0.000", nil}, 734 } 735 for _, tt := range tests { 736 var a, b, to Decimal 737 err := a.FromString(tt.a) 738 require.NoError(t, err) 739 err = b.FromString(tt.b) 740 require.NoError(t, err) 741 ec := DecimalMod(&a, &b, &to) 742 require.Equal(t, tt.err, ec) 743 if tt.err == ErrDivByZero { 744 continue 745 } 746 result := to.ToString() 747 require.Equal(t, tt.result, string(result)) 748 } 749 750 tests = []tcase{ 751 {"1", "1", "1.0000", nil}, 752 {"1.00", "1", "1.000000", nil}, 753 {"1", "1.000", "1.0000", nil}, 754 {"2", "3", "0.6667", nil}, 755 {"51", "0.003430", "14868.8047", nil}, 756 {"0.000", "0.1", "0.0000000", nil}, 757 } 758 for _, tt := range tests { 759 var a, b, to Decimal 760 err := a.FromString(tt.a) 761 require.NoError(t, err) 762 err = b.FromString(tt.b) 763 require.NoError(t, err) 764 ec := DecimalDiv(&a, &b, &to, DivFracIncr) 765 require.Equal(t, tt.err, ec) 766 if tt.err == ErrDivByZero { 767 continue 768 } 769 require.Equal(t, tt.result, to.String()) 770 } 771 772 tests = []tcase{ 773 {"1", "2.0", "1.0", nil}, 774 {"1.0", "2", "1.0", nil}, 775 {"2.23", "3", "2.23", nil}, 776 {"51", "0.003430", "0.002760", nil}, 777 } 778 for _, tt := range tests { 779 var a, b, to Decimal 780 err := a.FromString(tt.a) 781 require.NoError(t, err) 782 err = b.FromString(tt.b) 783 require.NoError(t, err) 784 ec := DecimalMod(&a, &b, &to) 785 require.Equal(t, tt.err, ec) 786 if tt.err == ErrDivByZero { 787 continue 788 } 789 require.Equal(t, tt.result, to.String()) 790 } 791 } 792 793 func TestMaxOrMinMyDecimal(t *testing.T) { 794 type tcase struct { 795 neg bool 796 prec int 797 frac int 798 result string 799 } 800 tests := []tcase{ 801 {true, 2, 1, "-9.9"}, 802 {false, 1, 1, "0.9"}, 803 {true, 1, 0, "-9"}, 804 {false, 0, 0, "0"}, 805 {false, 4, 2, "99.99"}, 806 } 807 for _, tt := range tests { 808 dec := NewMaxOrMinDec(tt.neg, tt.prec, tt.frac) 809 require.Equal(t, tt.result, dec.String()) 810 } 811 } 812 813 func TestReset(t *testing.T) { 814 var x1, y1, z1 Decimal 815 require.NoError(t, x1.FromString("38520.130741106671")) 816 require.NoError(t, y1.FromString("9863.944799797851")) 817 require.NoError(t, DecimalAdd(&x1, &y1, &z1)) 818 819 var x2, y2, z2 Decimal 820 require.NoError(t, x2.FromString("121519.080207244")) 821 require.NoError(t, y2.FromString("54982.444519146")) 822 require.NoError(t, DecimalAdd(&x2, &y2, &z2)) 823 824 require.NoError(t, DecimalAdd(&x2, &y2, &z1)) 825 require.Equal(t, z2, z1) 826 } 827 828 // this test will change global variable `wordBufLen`, so it must run in serial 829 func TestShiftMyDecimal(t *testing.T) { 830 type tcase struct { 831 input string 832 shift int 833 output string 834 err error 835 } 836 837 var dotest = func(tests []tcase) { 838 for _, test := range tests { 839 t.Run(fmt.Sprintf("%v (shift: %v, wordBufLen: %v)", test.input, test.shift, wordBufLen), func(t *testing.T) { 840 var dec Decimal 841 require.NoError(t, dec.FromString(test.input)) 842 require.Equal(t, test.err, dec.Shift(test.shift)) 843 require.Equal(t, test.output, string(dec.ToString())) 844 }) 845 } 846 } 847 848 wordBufLen = maxWordBufLen 849 tests := []tcase{ 850 {"123.123", 1, "1231.23", nil}, 851 {"123457189.123123456789000", 1, "1234571891.23123456789", nil}, 852 {"123457189.123123456789000", 8, "12345718912312345.6789", nil}, 853 {"123457189.123123456789000", 9, "123457189123123456.789", nil}, 854 {"123457189.123123456789000", 10, "1234571891231234567.89", nil}, 855 {"123457189.123123456789000", 17, "12345718912312345678900000", nil}, 856 {"123457189.123123456789000", 18, "123457189123123456789000000", nil}, 857 {"123457189.123123456789000", 19, "1234571891231234567890000000", nil}, 858 {"123457189.123123456789000", 26, "12345718912312345678900000000000000", nil}, 859 {"123457189.123123456789000", 27, "123457189123123456789000000000000000", nil}, 860 {"123457189.123123456789000", 28, "1234571891231234567890000000000000000", nil}, 861 {"000000000000000000000000123457189.123123456789000", 26, "12345718912312345678900000000000000", nil}, 862 {"00000000123457189.123123456789000", 27, "123457189123123456789000000000000000", nil}, 863 {"00000000000000000123457189.123123456789000", 28, "1234571891231234567890000000000000000", nil}, 864 {"123", 1, "1230", nil}, 865 {"123", 10, "1230000000000", nil}, 866 {".123", 1, "1.23", nil}, 867 {".123", 10, "1230000000", nil}, 868 {".123", 14, "12300000000000", nil}, 869 {"000.000", 1000, "0", nil}, 870 {"000.", 1000, "0", nil}, 871 {".000", 1000, "0", nil}, 872 {"1", 1000, "1", ErrOverflow}, 873 {"123.123", -1, "12.3123", nil}, 874 {"123987654321.123456789000", -1, "12398765432.1123456789", nil}, 875 {"123987654321.123456789000", -2, "1239876543.21123456789", nil}, 876 {"123987654321.123456789000", -3, "123987654.321123456789", nil}, 877 {"123987654321.123456789000", -8, "1239.87654321123456789", nil}, 878 {"123987654321.123456789000", -9, "123.987654321123456789", nil}, 879 {"123987654321.123456789000", -10, "12.3987654321123456789", nil}, 880 {"123987654321.123456789000", -11, "1.23987654321123456789", nil}, 881 {"123987654321.123456789000", -12, "0.123987654321123456789", nil}, 882 {"123987654321.123456789000", -13, "0.0123987654321123456789", nil}, 883 {"123987654321.123456789000", -14, "0.00123987654321123456789", nil}, 884 {"00000087654321.123456789000", -14, "0.00000087654321123456789", nil}, 885 } 886 dotest(tests) 887 888 wordBufLen = 2 889 tests = []tcase{ 890 {"123.123", -2, "1.23123", nil}, 891 {"123.123", -3, "0.123123", nil}, 892 {"123.123", -6, "0.000123123", nil}, 893 {"123.123", -7, "0.0000123123", nil}, 894 {"123.123", -15, "0.000000000000123123", nil}, 895 {"123.123", -16, "0.000000000000012312", ErrTruncated}, 896 {"123.123", -17, "0.000000000000001231", ErrTruncated}, 897 {"123.123", -18, "0.000000000000000123", ErrTruncated}, 898 {"123.123", -19, "0.000000000000000012", ErrTruncated}, 899 {"123.123", -20, "0.000000000000000001", ErrTruncated}, 900 {"123.123", -21, "0", ErrTruncated}, 901 {".000000000123", -1, "0.0000000000123", nil}, 902 {".000000000123", -6, "0.000000000000000123", nil}, 903 {".000000000123", -7, "0.000000000000000012", ErrTruncated}, 904 {".000000000123", -8, "0.000000000000000001", ErrTruncated}, 905 {".000000000123", -9, "0", ErrTruncated}, 906 {".000000000123", 1, "0.00000000123", nil}, 907 {".000000000123", 8, "0.0123", nil}, 908 {".000000000123", 9, "0.123", nil}, 909 {".000000000123", 10, "1.23", nil}, 910 {".000000000123", 17, "12300000", nil}, 911 {".000000000123", 18, "123000000", nil}, 912 {".000000000123", 19, "1230000000", nil}, 913 {".000000000123", 20, "12300000000", nil}, 914 {".000000000123", 21, "123000000000", nil}, 915 {".000000000123", 22, "1230000000000", nil}, 916 {".000000000123", 23, "12300000000000", nil}, 917 {".000000000123", 24, "123000000000000", nil}, 918 {".000000000123", 25, "1230000000000000", nil}, 919 {".000000000123", 26, "12300000000000000", nil}, 920 {".000000000123", 27, "123000000000000000", nil}, 921 {".000000000123", 28, "0.000000000123", ErrOverflow}, 922 {"123456789.987654321", -1, "12345678.998765432", ErrTruncated}, 923 {"123456789.987654321", -2, "1234567.899876543", ErrTruncated}, 924 {"123456789.987654321", -8, "1.234567900", ErrTruncated}, 925 {"123456789.987654321", -9, "0.123456789987654321", nil}, 926 {"123456789.987654321", -10, "0.012345678998765432", ErrTruncated}, 927 {"123456789.987654321", -17, "0.000000001234567900", ErrTruncated}, 928 {"123456789.987654321", -18, "0.000000000123456790", ErrTruncated}, 929 {"123456789.987654321", -19, "0.000000000012345679", ErrTruncated}, 930 {"123456789.987654321", -26, "0.000000000000000001", ErrTruncated}, 931 {"123456789.987654321", -27, "0", ErrTruncated}, 932 {"123456789.987654321", 1, "1234567900", ErrTruncated}, 933 {"123456789.987654321", 2, "12345678999", ErrTruncated}, 934 {"123456789.987654321", 4, "1234567899877", ErrTruncated}, 935 {"123456789.987654321", 8, "12345678998765432", ErrTruncated}, 936 {"123456789.987654321", 9, "123456789987654321", nil}, 937 {"123456789.987654321", 10, "123456789.987654321", ErrOverflow}, 938 {"123456789.987654321", 0, "123456789.987654321", nil}, 939 } 940 dotest(tests) 941 942 // reset 943 wordBufLen = maxWordBufLen 944 } 945 946 // this test will change global variable `wordBufLen`, so it must run in serial 947 func TestFromStringMyDecimal(t *testing.T) { 948 type tcase struct { 949 input string 950 output string 951 err error 952 } 953 954 var dotest = func(tests []tcase) { 955 for _, test := range tests { 956 t.Run(fmt.Sprintf("%v (wordBufLen: %v)", test.input, wordBufLen), func(t *testing.T) { 957 var dec Decimal 958 require.Equal(t, test.err, dec.FromString(test.input)) 959 require.Equal(t, test.output, string(dec.ToString())) 960 }) 961 } 962 } 963 964 wordBufLen = maxWordBufLen 965 tests := []tcase{ 966 {"12345", "12345", nil}, 967 {"12345.", "12345", nil}, 968 {"123.45.", "123.45", ErrTruncated}, 969 {"-123.45.", "-123.45", ErrTruncated}, 970 {".00012345000098765", "0.00012345000098765", nil}, 971 {".12345000098765", "0.12345000098765", nil}, 972 {"-.000000012345000098765", "-0.000000012345000098765", nil}, 973 {"1234500009876.5", "1234500009876.5", nil}, 974 {"123E5", "12300000", nil}, 975 {"123E-2", "1.23", nil}, 976 {"1e1073741823", "999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow}, 977 {"-1e1073741823", "-999999999999999999999999999999999999999999999999999999999999999999999999999999999", ErrOverflow}, 978 {"1e18446744073709551620", "0", ErrBadNumber}, 979 {"1e", "1", ErrTruncated}, 980 {"1e001", "10", nil}, 981 {"1e00", "1", nil}, 982 {"1eabc", "1", ErrTruncated}, 983 {"1e 1dddd ", "10", ErrTruncated}, 984 {"1e - 1", "1", ErrTruncated}, 985 {"1e -1", "0.1", nil}, 986 {"0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0.000000000000000000000000000000000000000000000000000000000000000000000000", ErrTruncated}, 987 {"1asf", "1", ErrTruncated}, 988 {"1.1.1.1.1", "1.1", ErrTruncated}, 989 {"1 1", "1", ErrTruncated}, 990 {"1 ", "1", nil}, 991 } 992 dotest(tests) 993 994 wordBufLen = 1 995 tests = []tcase{ 996 {"123450000098765", "98765", ErrOverflow}, 997 {"123450.000098765", "123450", ErrTruncated}, 998 } 999 dotest(tests) 1000 1001 // reset 1002 wordBufLen = maxWordBufLen 1003 }