github.com/matrixorigin/matrixone@v1.2.0/pkg/container/types/decimal.go (about) 1 // Copyright 2021 Matrix Origin 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package types 16 17 import ( 18 "encoding/binary" 19 "fmt" 20 "math" 21 "math/bits" 22 23 "github.com/matrixorigin/matrixone/pkg/common/moerr" 24 ) 25 26 var Pow10 = [20]uint64{ 27 1, 28 10, 29 100, 30 1000, 31 10000, 32 100000, 33 1000000, 34 10000000, 35 100000000, 36 1000000000, 37 10000000000, 38 100000000000, 39 1000000000000, 40 10000000000000, 41 100000000000000, 42 1000000000000000, 43 10000000000000000, 44 100000000000000000, 45 1000000000000000000, 46 10000000000000000000, 47 } 48 49 var FloatHigh = float64(1<<63) * 2 50 var Decimal64Min = Decimal64(uint64(1) << 63) 51 var Decimal64Max = ^Decimal64Min 52 var Decimal128Min = Decimal128{0, uint64(1) << 63} 53 var Decimal128Max = Decimal128{^uint64(0), ^Decimal128Min.B64_127} 54 55 func (x Decimal64) Sign() bool { 56 return x>>63 == 1 57 } 58 59 func (x Decimal128) Sign() bool { 60 return x.B64_127>>63 == 1 61 } 62 63 func (x Decimal256) Sign() bool { 64 return x.B192_255>>63 == 1 65 } 66 67 func (x Decimal64) Minus() Decimal64 { 68 return ^x + 1 69 } 70 71 func (x *Decimal128) MinusInplace() { 72 if x.B0_63 == 0 { 73 x.B64_127 = ^x.B64_127 + 1 74 } else { 75 x.B64_127 = ^x.B64_127 76 x.B0_63 = ^x.B0_63 + 1 77 } 78 } 79 80 func (x Decimal128) Minus() Decimal128 { 81 if x.B0_63 == 0 { 82 x.B64_127 = ^x.B64_127 + 1 83 } else { 84 x.B64_127 = ^x.B64_127 85 x.B0_63 = ^x.B0_63 + 1 86 } 87 return x 88 } 89 90 func (x Decimal256) Minus() Decimal256 { 91 x.B192_255 = ^x.B192_255 92 x.B128_191 = ^x.B128_191 93 x.B64_127 = ^x.B64_127 94 x.B0_63 = ^x.B0_63 + 1 95 if x.B0_63 == 0 { 96 x.B64_127++ 97 if x.B64_127 == 0 { 98 x.B128_191++ 99 if x.B128_191 == 0 { 100 x.B192_255++ 101 } 102 } 103 } 104 return x 105 } 106 107 func (x Decimal64) Less(y Decimal64) bool { 108 if x.Sign() != y.Sign() { 109 return x.Sign() 110 } 111 return x < y 112 } 113 114 func (x Decimal128) Less(y Decimal128) bool { 115 if x.Sign() != y.Sign() { 116 return x.Sign() 117 } 118 if x.Sign() { 119 x = x.Minus() 120 y = y.Minus() 121 if x.B64_127 != y.B64_127 { 122 return x.B64_127 > y.B64_127 123 } else { 124 return x.B0_63 > y.B0_63 125 } 126 } 127 if x.B64_127 != y.B64_127 { 128 return x.B64_127 < y.B64_127 129 } else { 130 return x.B0_63 < y.B0_63 131 } 132 } 133 134 func (x Decimal256) Less(y Decimal256) bool { 135 if x.Sign() != y.Sign() { 136 return x.Sign() 137 } 138 if x.Sign() { 139 x = x.Minus() 140 y = y.Minus() 141 if x.B192_255 != y.B192_255 { 142 return x.B192_255 > y.B192_255 143 } else if x.B128_191 != y.B128_191 { 144 return x.B128_191 > y.B128_191 145 } else if x.B64_127 != y.B64_127 { 146 return x.B64_127 > y.B64_127 147 } else { 148 return x.B0_63 > y.B0_63 149 } 150 } 151 if x.B192_255 != y.B192_255 { 152 return x.B192_255 < y.B192_255 153 } else if x.B128_191 != y.B128_191 { 154 return x.B128_191 < y.B128_191 155 } else if x.B64_127 != y.B64_127 { 156 return x.B64_127 < y.B64_127 157 } else { 158 return x.B0_63 < y.B0_63 159 } 160 } 161 162 func (x Decimal64) Compare(y Decimal64) int { 163 if x.Less(y) { 164 return -1 165 } else if x == y { 166 return 0 167 } else { 168 return 1 169 } 170 } 171 172 func (x Decimal128) Compare(y Decimal128) int { 173 if x.Less(y) { 174 return -1 175 } else if x == y { 176 return 0 177 } else { 178 return 1 179 } 180 } 181 182 func (x Decimal256) Compare(y Decimal256) int { 183 if x.Less(y) { 184 return -1 185 } else if x == y { 186 return 0 187 } else { 188 return 1 189 } 190 } 191 192 func CompareDecimal64(x Decimal64, y Decimal64) int { 193 return x.Compare(y) 194 } 195 196 func CompareDecimal128(x Decimal128, y Decimal128) int { 197 return x.Compare(y) 198 } 199 200 func CompareDecimal64WithScale(x, y Decimal64, scale1, scale2 int32) int { 201 if x.Sign() != y.Sign() { 202 if x.Sign() { 203 return -1 204 } else { 205 return 1 206 } 207 } 208 var err error 209 if scale1 < scale2 { 210 x, err = x.Scale(scale2 - scale1) 211 if err != nil { 212 if x.Sign() { 213 return -1 214 } else { 215 return 1 216 } 217 } 218 return x.Compare(y) 219 } else { 220 y, err = y.Scale(scale1 - scale2) 221 if err != nil { 222 if x.Sign() { 223 return 1 224 } else { 225 return -1 226 } 227 } 228 return x.Compare(y) 229 } 230 } 231 232 func CompareDecimal128WithScale(x, y Decimal128, scale1, scale2 int32) int { 233 if x.Sign() != y.Sign() { 234 if x.Sign() { 235 return -1 236 } else { 237 return 1 238 } 239 } 240 var err error 241 if scale1 < scale2 { 242 x, err = x.Scale(scale2 - scale1) 243 if err != nil { 244 if x.Sign() { 245 return -1 246 } else { 247 return 1 248 } 249 } 250 return x.Compare(y) 251 } else { 252 y, err = y.Scale(scale1 - scale2) 253 if err != nil { 254 if x.Sign() { 255 return 1 256 } else { 257 return -1 258 } 259 } 260 return x.Compare(y) 261 } 262 } 263 264 func CompareDecimal256(x Decimal256, y Decimal256) int { 265 return x.Compare(y) 266 } 267 268 func (x Decimal64) Lt(y Decimal64) bool { 269 return x.Less(y) 270 } 271 272 func (x Decimal128) Lt(y Decimal128) bool { 273 return x.Less(y) 274 } 275 276 func (x Decimal64) Left(n int) (y Decimal64) { 277 return x << n 278 } 279 280 func (x Decimal64) Right(n int) (y Decimal64) { 281 return Decimal64(int64(x) >> n) 282 } 283 284 func (x Decimal128) Left(n int) (y Decimal128) { 285 if n > 64 { 286 y.B64_127 = x.B0_63 << (n - 64) 287 y.B0_63 = 0 288 289 } else { 290 y.B64_127 = x.B64_127<<n | x.B0_63>>(64-n) 291 y.B0_63 = x.B0_63 << n 292 } 293 return 294 } 295 296 func (x Decimal128) Right(n int) (y Decimal128) { 297 sign := x.Sign() 298 if sign { 299 x = x.Minus() 300 } 301 if n > 64 { 302 y.B64_127 = 0 303 y.B0_63 = x.B64_127 >> (n - 64) 304 } else { 305 y.B64_127 = x.B64_127 >> n 306 y.B0_63 = x.B0_63>>n | x.B64_127<<(64-n) 307 } 308 if sign { 309 y = y.Minus() 310 } 311 return 312 } 313 314 func (x Decimal256) Left(n int) (y Decimal256) { 315 for n > 64 { 316 n -= 64 317 x.B192_255 = x.B128_191 318 x.B128_191 = x.B64_127 319 x.B64_127 = x.B0_63 320 x.B0_63 = 0 321 } 322 y.B192_255 = x.B192_255<<n | x.B128_191>>(64-n) 323 y.B128_191 = x.B128_191<<n | x.B64_127>>(64-n) 324 y.B64_127 = x.B64_127<<n | x.B0_63>>(64-n) 325 y.B0_63 = x.B0_63 << n 326 return 327 } 328 329 func (x Decimal256) Right(n int) (y Decimal256) { 330 sign := x.Sign() 331 if sign { 332 x = x.Minus() 333 } 334 for n > 64 { 335 n -= 64 336 x.B0_63 = x.B64_127 337 x.B64_127 = x.B128_191 338 x.B128_191 = x.B192_255 339 x.B192_255 = 0 340 } 341 y.B0_63 = x.B0_63>>n | x.B64_127<<(64-n) 342 y.B64_127 = x.B64_127>>n | x.B128_191<<(64-n) 343 y.B128_191 = x.B128_191>>n | x.B192_255<<(64-n) 344 y.B192_255 = x.B192_255 >> n 345 if sign { 346 y = y.Minus() 347 } 348 return 349 } 350 351 func (x Decimal64) Scale(n int32) (Decimal64, error) { 352 signx := x.Sign() 353 x1 := x 354 if signx { 355 x1 = x1.Minus() 356 } 357 err := error(nil) 358 m := int32(0) 359 for n-m > 19 || n-m < -19 { 360 if n > 0 { 361 m += 19 362 x1, err = x1.Mul64(Decimal64(Pow10[19])) 363 } else { 364 m -= 19 365 x1, err = x1.Div64(Decimal64(Pow10[19])) 366 } 367 if err != nil { 368 err = moerr.NewInvalidInputNoCtx("Decimal64 scale overflow: %s(Scale:%d)", x.Format(0), n) 369 return x, err 370 } 371 } 372 if n == m { 373 if signx { 374 x1 = x1.Minus() 375 } 376 return x1, nil 377 } 378 if n-m > 0 { 379 x1, err = x1.Mul64(Decimal64(Pow10[n-m])) 380 } else { 381 x1, err = x1.Div64(Decimal64(Pow10[m-n])) 382 } 383 if err != nil { 384 err = moerr.NewInvalidInputNoCtx("Decimal64 scale overflow: %s(Scale:%d)", x.Format(0), n) 385 return x, err 386 } 387 if signx { 388 x1 = x1.Minus() 389 } 390 return x1, err 391 } 392 393 func (x *Decimal128) ScaleInplace(n int32) error { 394 if n == 0 { 395 return nil 396 } 397 signx := x.Sign() 398 if signx { 399 x.MinusInplace() 400 } 401 m := int32(0) 402 var err error 403 for n-m > 19 || n-m < -19 { 404 if n > 0 { 405 m += 19 406 err = x.Mul64InPlace(Decimal64(Pow10[19])) 407 } else { 408 m -= 19 409 err = x.Div128InPlace(&Decimal128{Pow10[19], 0}) 410 } 411 if err != nil { 412 err = moerr.NewInvalidInputNoCtx("Decimal128 scale overflow: %s(Scale:%d)", x.Format(0), n) 413 return err 414 } 415 } 416 if n == m { 417 if signx { 418 x.MinusInplace() 419 } 420 return nil 421 } 422 if n-m > 0 { 423 err = x.Mul64InPlace(Decimal64(Pow10[n-m])) 424 } else { 425 err = x.Div128InPlace(&Decimal128{Pow10[m-n], 0}) 426 } 427 if err != nil { 428 err = moerr.NewInvalidInputNoCtx("Decimal128 scale overflow: %s(Scale:%d)", x.Format(0), n) 429 return err 430 } 431 if signx { 432 x.MinusInplace() 433 } 434 return nil 435 } 436 437 func (x Decimal128) Scale(n int32) (Decimal128, error) { 438 if n == 0 { 439 return x, nil 440 } 441 signx := x.Sign() 442 x1 := x 443 if signx { 444 x1 = x1.Minus() 445 } 446 err := error(nil) 447 m := int32(0) 448 for n-m > 19 || n-m < -19 { 449 if n > 0 { 450 m += 19 451 x1, err = x1.Mul128(Decimal128{Pow10[19], 0}) 452 } else { 453 m -= 19 454 x1, err = x1.Div128(Decimal128{Pow10[19], 0}) 455 } 456 if err != nil { 457 err = moerr.NewInvalidInputNoCtx("Decimal128 scale overflow: %s(Scale:%d)", x.Format(0), n) 458 return x, err 459 } 460 } 461 if n == m { 462 if signx { 463 x1 = x1.Minus() 464 } 465 return x1, nil 466 } 467 if n-m > 0 { 468 x1, err = x1.Mul128(Decimal128{Pow10[n-m], 0}) 469 } else { 470 x1, err = x1.Div128(Decimal128{Pow10[m-n], 0}) 471 } 472 if err != nil { 473 err = moerr.NewInvalidInputNoCtx("Decimal128 scale overflow: %s(Scale:%d)", x.Format(0), n) 474 return x, err 475 } 476 if signx { 477 x1 = x1.Minus() 478 } 479 return x1, err 480 } 481 482 func (x Decimal256) Scale(n int32) (Decimal256, error) { 483 signx := x.Sign() 484 x1 := x 485 if signx { 486 x1 = x1.Minus() 487 } 488 err := error(nil) 489 m := int32(0) 490 for n-m > 19 || n-m < -19 { 491 if n > 0 { 492 m += 19 493 x1, err = x1.Mul256(Decimal256{Pow10[19], 0, 0, 0}) 494 } else { 495 m -= 19 496 x1, err = x1.Div256(Decimal256{Pow10[19], 0, 0, 0}) 497 } 498 if err != nil { 499 err = moerr.NewInvalidInputNoCtx("Decimal256 scale overflow: %s(Scale:%d)", x.Format(0), n) 500 return x, err 501 } 502 } 503 if n == m { 504 if signx { 505 x1 = x1.Minus() 506 } 507 return x1, nil 508 } 509 if n-m > 0 { 510 x1, err = x1.Mul256(Decimal256{Pow10[n-m], 0, 0, 0}) 511 } else { 512 x1, err = x1.Div256(Decimal256{Pow10[m-n], 0, 0, 0}) 513 } 514 if err != nil { 515 err = moerr.NewInvalidInputNoCtx("Decimal256 Scale overflow: %s(Scale:%d)", x.Format(0), n) 516 return x, err 517 } 518 if signx { 519 x1 = x1.Minus() 520 } 521 return x1, err 522 } 523 524 func (x Decimal64) Add64(y Decimal64) (Decimal64, error) { 525 signx := x.Sign() 526 err := error(nil) 527 z := x + y 528 if signx == y.Sign() && signx != z.Sign() { 529 err = moerr.NewInvalidInputNoCtx("Decimal64 Add overflow: %s+%s", x.Format(0), y.Format(0)) 530 } 531 return z, err 532 } 533 534 func (x Decimal128) Add128(y Decimal128) (Decimal128, error) { 535 signx := x.Sign() 536 err := error(nil) 537 if signx == y.Sign() { 538 z := x 539 z.B0_63, z.B64_127 = bits.Add64(x.B0_63, y.B0_63, 0) 540 z.B64_127, _ = bits.Add64(x.B64_127, y.B64_127, z.B64_127) 541 if signx != z.Sign() { 542 err = moerr.NewInvalidInputNoCtx("Decimal128 Add overflow: %s+%s", x.Format(0), y.Format(0)) 543 } 544 return z, err 545 } else { 546 x.B0_63, y.B0_63 = bits.Add64(x.B0_63, y.B0_63, 0) 547 x.B64_127, _ = bits.Add64(x.B64_127, y.B64_127, y.B0_63) 548 } 549 return x, err 550 } 551 552 func (x Decimal256) Add256(y Decimal256) (Decimal256, error) { 553 signx := x.Sign() 554 err := error(nil) 555 if signx == y.Sign() { 556 z := x 557 z.B0_63, z.B64_127 = bits.Add64(x.B0_63, y.B0_63, 0) 558 z.B64_127, z.B128_191 = bits.Add64(x.B64_127, y.B64_127, z.B64_127) 559 z.B128_191, z.B192_255 = bits.Add64(x.B128_191, y.B128_191, z.B128_191) 560 z.B192_255, _ = bits.Add64(x.B192_255, y.B192_255, z.B192_255) 561 if signx != z.Sign() { 562 err = moerr.NewInvalidInputNoCtx("Decimal256 Add overflow: %s+%s", x.Format(0), y.Format(0)) 563 } 564 return z, err 565 } else { 566 x.B0_63, y.B0_63 = bits.Add64(x.B0_63, y.B0_63, 0) 567 x.B64_127, y.B64_127 = bits.Add64(x.B64_127, y.B64_127, y.B0_63) 568 x.B128_191, y.B128_191 = bits.Add64(x.B128_191, y.B128_191, y.B64_127) 569 x.B192_255, _ = bits.Add64(x.B192_255, y.B192_255, y.B128_191) 570 } 571 return x, err 572 } 573 574 func (x Decimal64) Sub64(y Decimal64) (Decimal64, error) { 575 z, err := x.Add64(y.Minus()) 576 if err != nil { 577 err = moerr.NewInvalidInputNoCtx("Decimal64 Sub overflow: %s-%s", x.Format(0), y.Format(0)) 578 } 579 return z, err 580 } 581 582 func (x Decimal128) Sub128(y Decimal128) (Decimal128, error) { 583 z, err := x.Add128(y.Minus()) 584 if err != nil { 585 err = moerr.NewInvalidInputNoCtx("Decimal128 Sub overflow: %s-%s", x.Format(0), y.Format(0)) 586 } 587 return z, err 588 } 589 590 func (x Decimal256) Sub256(y Decimal256) (Decimal256, error) { 591 z, err := x.Add256(y.Minus()) 592 if err != nil { 593 err = moerr.NewInvalidInputNoCtx("Decimal256 Sub overflow: %s-%s", x.Format(0), y.Format(0)) 594 } 595 return z, err 596 } 597 598 func (x Decimal64) Mul64(y Decimal64) (Decimal64, error) { 599 err := error(nil) 600 if x == 0 || y == 0 { 601 return Decimal64(0), err 602 } 603 z := x * y 604 if z/x != y { 605 err = moerr.NewInvalidInputNoCtx("Decimal64 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 606 } 607 return z, err 608 } 609 610 func (x *Decimal128) Mul64InPlace(y Decimal64) error { 611 z := Decimal128{0, 0} 612 z.B64_127, z.B0_63 = bits.Mul64(x.B0_63, uint64(y)) 613 w := Decimal128{0, 0} 614 if x.B64_127 != 0 { 615 w.B0_63, w.B64_127 = bits.Mul64(x.B64_127, uint64(y)) 616 } 617 if w.B0_63 != 0 || w.Sign() || z.Sign() { 618 return moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 619 } 620 z.B64_127 += w.B64_127 621 if z.Sign() { 622 return moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 623 } 624 *x = z 625 return nil 626 } 627 628 func (x *Decimal128) Mul128InPlace(y *Decimal128) error { 629 if x.B64_127 != 0 && y.B64_127 != 0 { 630 return moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 631 } 632 z := Decimal128{0, 0} 633 z.B64_127, z.B0_63 = bits.Mul64(x.B0_63, y.B0_63) 634 w := Decimal128{0, 0} 635 if x.B64_127 == 0 { 636 w.B0_63, w.B64_127 = bits.Mul64(x.B0_63, y.B64_127) 637 } else { 638 w.B0_63, w.B64_127 = bits.Mul64(x.B64_127, y.B0_63) 639 } 640 if w.B0_63 != 0 || w.Sign() || z.Sign() { 641 return moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 642 } 643 z.B64_127 += w.B64_127 644 if z.Sign() { 645 return moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 646 } 647 *x = z 648 return nil 649 } 650 651 func (x Decimal128) Mul128(y Decimal128) (Decimal128, error) { 652 if x.B64_127 != 0 && y.B64_127 != 0 { 653 return x, moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 654 } 655 z := Decimal128{0, 0} 656 z.B64_127, z.B0_63 = bits.Mul64(x.B0_63, y.B0_63) 657 w := Decimal128{0, 0} 658 if x.B64_127 == 0 { 659 w.B0_63, w.B64_127 = bits.Mul64(x.B0_63, y.B64_127) 660 } else { 661 w.B0_63, w.B64_127 = bits.Mul64(x.B64_127, y.B0_63) 662 } 663 if w.B0_63 != 0 || w.Sign() || z.Sign() { 664 return z, moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 665 } 666 z.B64_127 += w.B64_127 667 if z.Sign() { 668 return z, moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s*%s", x.Format(0), y.Format(0)) 669 } 670 return z, nil 671 } 672 673 func (x Decimal256) Mul256(y Decimal256) (Decimal256, error) { 674 if x.B192_255 != 0 && (y.B192_255 != 0 || y.B128_191 != 0 || y.B64_127 != 0) { 675 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 676 } 677 if x.B128_191 != 0 && (y.B192_255 != 0 || y.B128_191 != 0) { 678 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 679 } 680 if x.B64_127 != 0 && y.B192_255 != 0 { 681 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 682 } 683 z := Decimal256{0, 0, 0, 0} 684 var hi, lo, ca uint64 685 z.B64_127, z.B0_63 = bits.Mul64(x.B0_63, y.B0_63) 686 z.B128_191, lo = bits.Mul64(x.B0_63, y.B64_127) 687 z.B64_127, ca = bits.Add64(z.B64_127, lo, 0) 688 hi, lo = bits.Mul64(x.B64_127, y.B0_63) 689 z.B128_191, z.B192_255 = bits.Add64(z.B128_191, hi, ca) 690 z.B64_127, ca = bits.Add64(z.B64_127, lo, 0) 691 hi, lo = bits.Mul64(x.B128_191, y.B0_63) 692 z.B128_191, ca = bits.Add64(z.B128_191, lo, ca) 693 z.B192_255, ca = bits.Add64(z.B192_255, hi, ca) 694 if ca != 0 { 695 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 696 } 697 hi, lo = bits.Mul64(x.B64_127, y.B64_127) 698 z.B128_191, ca = bits.Add64(z.B128_191, lo, 0) 699 z.B192_255, ca = bits.Add64(z.B192_255, hi, ca) 700 if ca != 0 { 701 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 702 } 703 hi, lo = bits.Mul64(x.B0_63, y.B128_191) 704 z.B128_191, ca = bits.Add64(z.B128_191, lo, 0) 705 z.B192_255, ca = bits.Add64(z.B192_255, hi, ca) 706 if ca != 0 { 707 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 708 } 709 hi, lo = bits.Mul64(x.B192_255, y.B0_63) 710 if hi != 0 { 711 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 712 } 713 z.B192_255, ca = bits.Add64(z.B192_255, lo, 0) 714 if ca != 0 { 715 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 716 } 717 hi, lo = bits.Mul64(x.B128_191, y.B64_127) 718 if hi != 0 { 719 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 720 } 721 z.B192_255, ca = bits.Add64(z.B192_255, lo, 0) 722 if ca != 0 { 723 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 724 } 725 hi, lo = bits.Mul64(x.B64_127, y.B128_191) 726 if hi != 0 { 727 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 728 } 729 z.B192_255, ca = bits.Add64(z.B192_255, lo, 0) 730 if ca != 0 { 731 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 732 } 733 hi, lo = bits.Mul64(x.B0_63, y.B192_255) 734 if hi != 0 { 735 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 736 } 737 z.B192_255, ca = bits.Add64(z.B192_255, lo, 0) 738 if ca != 0 || z.B192_255>>63 != 0 { 739 return x, moerr.NewInvalidInputNoCtx("Decimal256 Mul overflow") 740 } 741 return z, nil 742 } 743 744 func (x Decimal64) Div64(y Decimal64) (Decimal64, error) { 745 if y == 0 { 746 return x, moerr.NewInvalidInputNoCtx("Decimal64 Div by Zero: %s/%s", x.Format(0), y.Format(0)) 747 } 748 z := x / y 749 if (x-z*y)*2 >= y { 750 z++ 751 } 752 return z, nil 753 } 754 755 func (x *Decimal128) Div128InPlace(y *Decimal128) error { 756 if y.B0_63 == 0 && y.B64_127 == 0 { 757 return moerr.NewInvalidInputNoCtx("Decimal128 Div by Zero: %s/%s", x.Format(0), y.Format(0)) 758 } 759 if y.B64_127 == 0 { 760 x.B64_127, y.B64_127 = bits.Div64(0, x.B64_127, y.B0_63) 761 x.B0_63, y.B64_127 = bits.Div64(y.B64_127, x.B0_63, y.B0_63) 762 if y.B64_127*2 >= y.B0_63 || y.B64_127>>63 != 0 { 763 x.B0_63++ 764 if x.B0_63 == 0 { 765 x.B64_127++ 766 } 767 } 768 } else { 769 if x.Less(*y) { 770 x.B64_127 = 0 771 x.B0_63 = 0 772 } else { 773 n := bits.LeadingZeros64(y.B64_127) 774 v, _ := bits.Div64(x.B64_127, x.B0_63, y.Right(64-n).B0_63) 775 v >>= 63 - n 776 if v&1 == 0 { 777 x.B0_63 = v >> 1 778 } else { 779 z, _ := y.Mul128(Decimal128{v, 0}) 780 if x.Left(1).Less(z) { 781 x.B0_63 = v >> 1 782 } else { 783 x.B0_63 = (v >> 1) + 1 784 } 785 } 786 x.B64_127 = 0 787 } 788 } 789 return nil 790 } 791 792 func (x Decimal128) Div128(y Decimal128) (Decimal128, error) { 793 if y.B0_63 == 0 && y.B64_127 == 0 { 794 return x, moerr.NewInvalidInputNoCtx("Decimal128 Div by Zero: %s/%s", x.Format(0), y.Format(0)) 795 } 796 if y.B64_127 == 0 { 797 x.B64_127, y.B64_127 = bits.Div64(0, x.B64_127, y.B0_63) 798 x.B0_63, y.B64_127 = bits.Div64(y.B64_127, x.B0_63, y.B0_63) 799 if y.B64_127*2 >= y.B0_63 || y.B64_127>>63 != 0 { 800 x.B0_63++ 801 if x.B0_63 == 0 { 802 x.B64_127++ 803 } 804 } 805 } else { 806 if x.Less(y) { 807 x.B64_127 = 0 808 x.B0_63 = 0 809 } else { 810 n := bits.LeadingZeros64(y.B64_127) 811 v, _ := bits.Div64(x.B64_127, x.B0_63, y.Right(64-n).B0_63) 812 v >>= 63 - n 813 if v&1 == 0 { 814 x.B0_63 = v >> 1 815 } else { 816 z, _ := y.Mul128(Decimal128{v, 0}) 817 if x.Left(1).Less(z) { 818 x.B0_63 = v >> 1 819 } else { 820 x.B0_63 = (v >> 1) + 1 821 } 822 } 823 x.B64_127 = 0 824 } 825 } 826 return x, nil 827 } 828 829 func (x Decimal256) Div256(y Decimal256) (Decimal256, error) { 830 if y.B128_191 == 0 && y.B192_255 == 0 && y.B64_127 == 0 { 831 if y.B0_63 == 0 { 832 return x, moerr.NewInvalidInputNoCtx("Decimal256 Div by Zero") 833 } 834 x = x.Left(1) 835 z := Decimal256{0, 0, 0, 0} 836 z.B192_255, z.B128_191 = bits.Div64(0, x.B192_255, y.B0_63) 837 z.B128_191, z.B64_127 = bits.Div64(z.B128_191, x.B128_191, y.B0_63) 838 z.B64_127, z.B0_63 = bits.Div64(z.B64_127, x.B64_127, y.B0_63) 839 z.B0_63, _ = bits.Div64(z.B0_63, x.B0_63, y.B0_63) 840 if z.B0_63&1 == 0 { 841 z = z.Right(1) 842 } else { 843 z, _ = z.Right(1).Add256(Decimal256{1, 0, 0, 0}) 844 } 845 return z, nil 846 } else { 847 x = x.Left(1) 848 w := Decimal256{1, 0, 0, 0} 849 z := Decimal256{0, 0, 0, 0} 850 for y.Compare(x) <= 0 { 851 y = y.Left(1) 852 w = w.Left(1) 853 } 854 for y.B0_63 != 0 || y.B64_127 != 0 || y.B128_191 != 0 || y.B192_255 != 0 { 855 y = y.Right(1) 856 w = w.Right(1) 857 if y.Compare(x) <= 0 { 858 z, _ = z.Add256(w) 859 x, _ = x.Sub256(y) 860 } 861 } 862 if z.B0_63&1 == 0 { 863 z = z.Right(1) 864 } else { 865 z, _ = z.Right(1).Add256(Decimal256{1, 0, 0, 0}) 866 } 867 return z, nil 868 } 869 } 870 871 func (x Decimal64) Mod64(y Decimal64) (Decimal64, error) { 872 if y == 0 { 873 return x, moerr.NewInvalidInputNoCtx("Decimal64 Mod by Zero: %s%%%s", x.Format(0), y.Format(0)) 874 } 875 return x % y, nil 876 } 877 878 func (x Decimal128) Mod128(y Decimal128) (Decimal128, error) { 879 if y.B0_63 == 0 && y.B64_127 == 0 { 880 return x, moerr.NewInvalidInputNoCtx("Decimal128 Mod by Zero: %s%%%s", x.Format(0), y.Format(0)) 881 } 882 if y.B64_127 == 0 { 883 _, x.B64_127 = bits.Div64(0, x.B64_127, y.B0_63) 884 _, x.B0_63 = bits.Div64(x.B64_127, x.B0_63, y.B0_63) 885 x.B64_127 = 0 886 } else { 887 if !x.Less(y) { 888 n := bits.LeadingZeros64(y.B64_127) 889 x1 := x.Right(1) 890 v, _ := bits.Div64(x1.B64_127, x1.B0_63, y.Right(64-n).B0_63) 891 v >>= 63 - n 892 x1, _ = y.Mul128(Decimal128{v - 1, 0}) 893 x, _ = x.Sub128(x1) 894 if !x.Less(y) { 895 x, _ = x.Sub128(y) 896 } 897 } 898 } 899 return x, nil 900 } 901 902 func (x Decimal256) Mod256(y Decimal256) (Decimal256, error) { 903 z, err := x.Div256(y) 904 if err != nil { 905 return x, err 906 } 907 z, err = z.Mul256(y) 908 if err != nil { 909 return x, err 910 } 911 z, err = x.Sub256(z) 912 return z, err 913 } 914 915 func (x Decimal64) Add(y Decimal64, scale1, scale2 int32) (z Decimal64, scale int32, err error) { 916 if scale1 > scale2 { 917 scale = scale1 918 y, err = y.Scale(scale - scale2) 919 } else { 920 scale = scale2 921 x, err = x.Scale(scale - scale1) 922 } 923 if err == nil { 924 z, err = x.Add64(y) 925 } 926 if err != nil { 927 err = moerr.NewInvalidInputNoCtx("Decimal64 Scales in Add overflow: %s(Scale:%d)+%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 928 } 929 return 930 } 931 932 func (x Decimal128) Add64(y Decimal64) (Decimal128, error) { 933 var err error 934 z := x 935 z.B0_63, z.B64_127 = bits.Add64(x.B0_63, uint64(y), 0) 936 if !y.Sign() { 937 z.B64_127, _ = bits.Add64(x.B64_127, 0, z.B64_127) 938 } else { 939 z.B64_127, _ = bits.Add64(x.B64_127, ^uint64(0), z.B64_127) 940 } 941 if x.Sign() == y.Sign() && x.Sign() != z.Sign() { 942 err = moerr.NewInvalidInputNoCtx("Decimal128 Add overflow: %s+%s", x.Format(0), y.Format(0)) 943 } 944 return z, err 945 } 946 947 // for performance sake, must make sure x and y has same scale, then call this function 948 func (x *Decimal128) AddInplace(y *Decimal128) (err error) { 949 signx := x.Sign() 950 var carryout uint64 951 if signx == y.Sign() { 952 x.B0_63, carryout = bits.Add64(x.B0_63, y.B0_63, 0) 953 x.B64_127, _ = bits.Add64(x.B64_127, y.B64_127, carryout) 954 if signx != x.Sign() { 955 err = moerr.NewInvalidInputNoCtx("Decimal128 Add overflow: %s+%s", x.Format(0), y.Format(0)) 956 return 957 } 958 } else { 959 x.B0_63, carryout = bits.Add64(x.B0_63, y.B0_63, 0) 960 x.B64_127, _ = bits.Add64(x.B64_127, y.B64_127, carryout) 961 } 962 return 963 } 964 965 func (x Decimal128) Add(y Decimal128, scale1, scale2 int32) (z Decimal128, scale int32, err error) { 966 if scale1 > scale2 { 967 scale = scale1 968 err = y.ScaleInplace(scale - scale2) 969 } else if scale1 < scale2 { 970 scale = scale2 971 err = x.ScaleInplace(scale - scale1) 972 } 973 if err == nil { 974 z, err = x.Add128(y) 975 } 976 if err != nil { 977 err = moerr.NewInvalidInputNoCtx("Decimal128 Scales in Add overflow: %s(Scale:%d)+%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 978 } 979 return 980 } 981 982 func (x Decimal64) Sub(y Decimal64, scale1, scale2 int32) (z Decimal64, scale int32, err error) { 983 if scale1 > scale2 { 984 scale = scale1 985 y, err = y.Scale(scale - scale2) 986 } else { 987 scale = scale2 988 x, err = x.Scale(scale - scale1) 989 } 990 if err == nil { 991 z, err = x.Sub64(y) 992 } 993 if err != nil { 994 err = moerr.NewInvalidInputNoCtx("Decimal64 Scales in Sub overflow: %s(Scale:%d)-%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 995 } 996 return 997 } 998 999 func (x Decimal128) Sub(y Decimal128, scale1, scale2 int32) (z Decimal128, scale int32, err error) { 1000 if scale1 > scale2 { 1001 scale = scale1 1002 err = y.ScaleInplace(scale - scale2) 1003 } else if scale1 < scale2 { 1004 scale = scale2 1005 err = x.ScaleInplace(scale - scale1) 1006 } 1007 if err == nil { 1008 z, err = x.Sub128(y) 1009 } 1010 if err != nil { 1011 err = moerr.NewInvalidInputNoCtx("Decimal128 Scales in Sub overflow: %s(Scale:%d)-%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1012 } 1013 return 1014 } 1015 1016 func (x Decimal64) Mul(y Decimal64, scale1, scale2 int32) (z Decimal64, scale int32, err error) { 1017 scale = 12 1018 if scale1 > scale { 1019 scale = scale1 1020 } 1021 if scale2 > scale { 1022 scale = scale2 1023 } 1024 if scale1+scale2 < scale { 1025 scale = scale1 + scale2 1026 } 1027 signx := x.Sign() 1028 x1 := x 1029 signy := y.Sign() 1030 y1 := y 1031 if signx { 1032 x1 = x1.Minus() 1033 } 1034 if signy { 1035 y1 = y1.Minus() 1036 } 1037 z, err = x1.Mul64(y1) 1038 if err != nil { 1039 x2 := Decimal128{uint64(x1), 0} 1040 y2 := Decimal128{uint64(y1), 0} 1041 x2, _ = x2.Mul128(y2) 1042 x2, _ = x2.Scale(scale - scale1 - scale2) 1043 if x2.B64_127 != 0 || x2.B0_63>>63 != 0 { 1044 err = moerr.NewInvalidInputNoCtx("Decimal64 Mul overflow: %s(Scale:%d)*%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1045 return 1046 } else { 1047 err = nil 1048 } 1049 z = Decimal64(x2.B0_63) 1050 if signx != signy { 1051 z = z.Minus() 1052 } 1053 return 1054 } 1055 if signx != signy { 1056 z = z.Minus() 1057 } 1058 return 1059 } 1060 1061 func (x *Decimal128) MulInplace(y *Decimal128, scale, scale1, scale2 int32) (err error) { 1062 signx := x.Sign() 1063 signy := y.Sign() 1064 if signx { 1065 x.MinusInplace() 1066 } 1067 if signy { 1068 tmp := *y 1069 tmp.MinusInplace() 1070 y = &tmp 1071 } 1072 err = x.Mul128InPlace(y) 1073 if err != nil { 1074 x2 := Decimal256{x.B0_63, x.B64_127, 0, 0} 1075 y2 := Decimal256{y.B0_63, y.B64_127, 0, 0} 1076 x2, _ = x2.Mul256(y2) 1077 x2, _ = x2.Scale(scale) 1078 if x2.B128_191 != 0 || x2.B192_255 != 0 || x2.B64_127>>63 != 0 { 1079 if signy { 1080 y.MinusInplace() 1081 } 1082 err = moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s(Scale:%d)*%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1083 return 1084 } else { 1085 err = nil 1086 } 1087 x.B0_63 = x2.B0_63 1088 x.B64_127 = x2.B64_127 1089 if signx != signy { 1090 x.MinusInplace() 1091 } 1092 return 1093 } 1094 if scale != 0 { 1095 x.ScaleInplace(scale) 1096 } 1097 if signx != signy { 1098 x.MinusInplace() 1099 } 1100 return 1101 } 1102 1103 func (x Decimal128) Mul(y Decimal128, scale1, scale2 int32) (z Decimal128, scale int32, err error) { 1104 scale = 12 1105 if scale1 > scale { 1106 scale = scale1 1107 } 1108 if scale2 > scale { 1109 scale = scale2 1110 } 1111 if scale1+scale2 < scale { 1112 scale = scale1 + scale2 1113 } 1114 signx := x.Sign() 1115 x1 := x 1116 signy := y.Sign() 1117 y1 := y 1118 if signx { 1119 x1.MinusInplace() 1120 } 1121 if signy { 1122 y1.MinusInplace() 1123 } 1124 z, err = x1.Mul128(y1) 1125 if err != nil { 1126 x2 := Decimal256{x1.B0_63, x1.B64_127, 0, 0} 1127 y2 := Decimal256{y1.B0_63, y1.B64_127, 0, 0} 1128 x2, _ = x2.Mul256(y2) 1129 x2, _ = x2.Scale(scale - scale1 - scale2) 1130 if x2.B128_191 != 0 || x2.B192_255 != 0 || x2.B64_127>>63 != 0 { 1131 err = moerr.NewInvalidInputNoCtx("Decimal128 Mul overflow: %s(Scale:%d)*%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1132 return 1133 } else { 1134 err = nil 1135 } 1136 z.B0_63 = x2.B0_63 1137 z.B64_127 = x2.B64_127 1138 if signx != signy { 1139 z = z.Minus() 1140 } 1141 return 1142 } 1143 if scale-scale1-scale2 != 0 { 1144 z.ScaleInplace(scale - scale1 - scale2) 1145 } 1146 if signx != signy { 1147 z.MinusInplace() 1148 } 1149 return 1150 } 1151 1152 func (x Decimal64) Div(y Decimal64, scale1, scale2 int32) (z Decimal64, scale int32, err error) { 1153 scale = 12 1154 if scale > scale1+6 { 1155 scale = scale1 + 6 1156 } 1157 if scale < scale1 { 1158 scale = scale1 1159 } 1160 signx := x.Sign() 1161 x1 := x 1162 signy := y.Sign() 1163 y1 := y 1164 if signx { 1165 x1 = x1.Minus() 1166 } 1167 if signy { 1168 y1 = y1.Minus() 1169 } 1170 z, err = x1.Scale(scale - scale1 + scale2) 1171 if err != nil { 1172 x2 := Decimal128{uint64(x1), 0} 1173 y2 := Decimal128{uint64(y1), 0} 1174 x2, err = x2.Scale(scale - scale1 + scale2) 1175 if err != nil { 1176 err = moerr.NewInvalidInputNoCtx("Decimal64 Scales in Div overflow: %s(Scale:%d)/%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1177 return 1178 } 1179 x2, err = x2.Div128(y2) 1180 if err != nil || x2.B64_127 != 0 || x2.B0_63>>63 != 0 { 1181 err = moerr.NewInvalidInputNoCtx("Decimal64 Div overflow: %s(Scale:%d)/%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1182 } 1183 z = Decimal64(x2.B0_63) 1184 return 1185 } 1186 z, err = z.Div64(y1) 1187 if signx != signy { 1188 z = z.Minus() 1189 } 1190 return 1191 } 1192 1193 func (x Decimal128) Div(y Decimal128, scale1, scale2 int32) (z Decimal128, scale int32, err error) { 1194 scale = 12 1195 if scale > scale1+6 { 1196 scale = scale1 + 6 1197 } 1198 if scale < scale1 { 1199 scale = scale1 1200 } 1201 signx := x.Sign() 1202 x1 := x 1203 signy := y.Sign() 1204 y1 := y 1205 if signx { 1206 x1 = x1.Minus() 1207 } 1208 if signy { 1209 y1 = y1.Minus() 1210 } 1211 z, err = x1.Scale(scale - scale1 + scale2) 1212 if err != nil { 1213 x2 := Decimal256{x1.B0_63, x1.B64_127, 0, 0} 1214 y2 := Decimal256{y1.B0_63, y1.B64_127, 0, 0} 1215 x2, err = x2.Scale(scale - scale1 + scale2) 1216 if err != nil { 1217 err = moerr.NewInvalidInputNoCtx("Decimal128 Div overflow: %s(Scale:%d)/%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1218 return 1219 } 1220 x2, err = x2.Div256(y2) 1221 if err != nil || x2.B192_255 != 0 || x2.B128_191 != 0 || x2.B64_127>>63 != 0 { 1222 err = moerr.NewInvalidInputNoCtx("Decimal128 Div overflow: %s(Scale:%d)/%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1223 } 1224 z.B0_63 = x2.B0_63 1225 z.B64_127 = x2.B64_127 1226 return 1227 } 1228 z, err = z.Div128(y1) 1229 if signx != signy { 1230 z = z.Minus() 1231 } 1232 return 1233 } 1234 1235 func (x Decimal64) Mod(y Decimal64, scale1, scale2 int32) (z Decimal64, scale int32, err error) { 1236 signx := x.Sign() 1237 x1 := x 1238 signy := y.Sign() 1239 y1 := y 1240 if signx { 1241 x1 = x1.Minus() 1242 } 1243 if signy { 1244 y1 = y1.Minus() 1245 } 1246 if scale1 > scale2 { 1247 scale = scale1 1248 y1, err = y1.Scale(scale - scale2) 1249 } else { 1250 scale = scale2 1251 x1, err = x1.Scale(scale - scale1) 1252 } 1253 if err != nil { 1254 x2 := Decimal128{uint64(x1), 0} 1255 y2 := Decimal128{uint64(y1), 0} 1256 if scale1 > scale2 { 1257 scale = scale1 1258 y2, err = y2.Scale(scale - scale2) 1259 } else { 1260 scale = scale2 1261 x2, err = x2.Scale(scale - scale1) 1262 } 1263 if err != nil { 1264 err = moerr.NewInvalidInputNoCtx("Decimal64 Mod overflow: %s(Scale:%d)%%%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1265 return 1266 } 1267 x2, err = x2.Mod128(y2) 1268 z = Decimal64(x2.B0_63) 1269 if signx { 1270 z = z.Minus() 1271 } 1272 return 1273 } 1274 z, err = x1.Mod64(y1) 1275 if signx { 1276 z = z.Minus() 1277 } 1278 return 1279 } 1280 1281 func (x Decimal128) Mod(y Decimal128, scale1, scale2 int32) (z Decimal128, scale int32, err error) { 1282 signx := x.Sign() 1283 x1 := x 1284 signy := y.Sign() 1285 y1 := y 1286 if signx { 1287 x1 = x1.Minus() 1288 } 1289 if signy { 1290 y1 = y1.Minus() 1291 } 1292 if scale1 > scale2 { 1293 scale = scale1 1294 y1, err = y1.Scale(scale - scale2) 1295 } else { 1296 scale = scale2 1297 x1, err = x1.Scale(scale - scale1) 1298 } 1299 if err != nil { 1300 x2 := Decimal256{x1.B0_63, x1.B64_127, 0, 0} 1301 y2 := Decimal256{y1.B0_63, y1.B64_127, 0, 0} 1302 if scale1 > scale2 { 1303 scale = scale1 1304 y2, err = y2.Scale(scale - scale2) 1305 } else { 1306 scale = scale2 1307 x2, err = x2.Scale(scale - scale1) 1308 } 1309 if err != nil { 1310 err = moerr.NewInvalidInputNoCtx("Decimal128 Mod overflow: %s(Scale:%d)%%%s(Scale:%d)", x.Format(0), scale1, y.Format(0), scale2) 1311 return 1312 } 1313 x2, err = x2.Mod256(y2) 1314 z.B0_63 = x2.B0_63 1315 z.B64_127 = x2.B64_127 1316 if signx { 1317 z = z.Minus() 1318 } 1319 return 1320 } 1321 z, err = x1.Mod128(y1) 1322 if signx { 1323 z = z.Minus() 1324 } 1325 return 1326 } 1327 1328 func Decimal64ToFloat64(x Decimal64, scale int32) float64 { 1329 signx := x.Sign() 1330 if signx { 1331 x = x.Minus() 1332 } 1333 y := float64(x) 1334 for scale > 19 { 1335 scale -= 19 1336 y /= float64(Pow10[19]) 1337 } 1338 y /= float64(Pow10[scale]) 1339 if signx { 1340 y = -y 1341 } 1342 return y 1343 } 1344 1345 func Decimal128ToFloat64(x Decimal128, scale int32) float64 { 1346 signx := x.Sign() 1347 if signx { 1348 x = x.Minus() 1349 } 1350 y := float64(x.B64_127) * FloatHigh 1351 y += float64(x.B0_63) 1352 for scale > 19 { 1353 scale -= 19 1354 y /= float64(Pow10[19]) 1355 } 1356 y /= float64(Pow10[scale]) 1357 if signx { 1358 y = -y 1359 } 1360 return y 1361 } 1362 1363 func Decimal64FromFloat64(x float64, width, scale int32) (y Decimal64, err error) { 1364 err = nil 1365 if x != x || x+1 == x || width > 18 || width < 1 || scale > width || scale < 0 { 1366 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal64: %f(%d,%d)", x, width, scale) 1367 return 1368 } 1369 z := x 1370 signx := false 1371 if x < 0 { 1372 z = -z 1373 signx = true 1374 } 1375 for scale > 19 { 1376 scale -= 19 1377 z *= float64(Pow10[19]) 1378 } 1379 z *= float64(Pow10[scale]) 1380 if z > float64(Pow10[width]) { 1381 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal64: %f(%d,%d)", x, width, scale) 1382 return 1383 } 1384 y = Decimal64(uint64(z * 2)) 1385 if y&1 == 1 { 1386 y++ 1387 } 1388 y >>= 1 1389 if uint64(y) >= Pow10[width] { 1390 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal64: %f(%d,%d)", x, width, scale) 1391 return 1392 } 1393 if signx { 1394 y = y.Minus() 1395 } 1396 return 1397 } 1398 1399 func Decimal128FromFloat64(x float64, width, scale int32) (y Decimal128, err error) { 1400 err = nil 1401 if math.IsInf(x, 0) || math.IsNaN(x) { 1402 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal128, Float64 is Inf or NaN") 1403 return 1404 } 1405 if width > 38 || width < 1 || scale > width || scale < 0 { 1406 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal128: %f(%d,%d)", x, width, scale) 1407 return 1408 } 1409 z := x 1410 signx := false 1411 n := scale 1412 if x < 0 { 1413 z = -z 1414 signx = true 1415 } 1416 for n > 19 { 1417 n -= 19 1418 z *= float64(Pow10[19]) 1419 } 1420 z *= float64(Pow10[n]) 1421 if z > FloatHigh { 1422 n = 0 1423 for z > FloatHigh { 1424 z /= 10 1425 n++ 1426 } 1427 if z < float64(Pow10[19]) { 1428 if n > 19 || width-n < 19 { 1429 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal128: %f(%d,%d)", x, width, scale) 1430 return 1431 } 1432 } else { 1433 if n > 18 || width-n < 20 { 1434 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal128: %f(%d,%d)", x, width, scale) 1435 return 1436 } 1437 } 1438 y.B64_127 = 0 1439 y.B0_63 = uint64(z) 1440 y, _ = y.Scale(n) 1441 } else { 1442 if z*2 > FloatHigh || uint64(z*2)&1 == 0 { 1443 y.B64_127 = 0 1444 y.B0_63 = uint64(z) 1445 } else { 1446 y.B64_127 = 0 1447 y.B0_63 = uint64(z) + 1 1448 } 1449 if width <= 19 && y.B0_63 >= Pow10[width] { 1450 err = moerr.NewInvalidInputNoCtx("Can't convert Float64 To Decimal128: %f(%d,%d)", x, width, scale) 1451 return 1452 } 1453 } 1454 if signx { 1455 y = y.Minus() 1456 } 1457 return 1458 } 1459 1460 func Decimal256FromInt64(x int64) Decimal256 { 1461 return Decimal256{uint64(x), 0, 0, 0} 1462 } 1463 1464 func Decimal256FromDecimal128(x Decimal128) Decimal256 { 1465 y := Decimal256{x.B0_63, x.B64_127, 0, 0} 1466 if x.Sign() { 1467 y.B128_191 = ^y.B128_191 1468 y.B192_255 = ^y.B192_255 1469 } 1470 return y 1471 } 1472 1473 func Decimal256ToFloat64(x Decimal256, scale int32) float64 { 1474 sign := x.Sign() 1475 if sign { 1476 x = x.Minus() 1477 } 1478 for x.B128_191 != 0 || x.B192_255 != 0 { 1479 x, _ = x.Scale(-1) 1480 scale-- 1481 } 1482 y := Decimal128ToFloat64(Decimal128{x.B0_63, x.B64_127}, scale) 1483 if sign { 1484 y = -y 1485 } 1486 return y 1487 } 1488 1489 func Parse64(x string) (y Decimal64, scale int32, err error) { 1490 y = Decimal64(0) 1491 z := Decimal64(0) 1492 scale = -1 1493 width := 0 1494 i := 0 1495 flag := false 1496 t := false 1497 floatflag := false 1498 scalecount := int32(0) 1499 scalesign := false 1500 signx := false 1501 err = nil 1502 if x[0] == '-' { 1503 i++ 1504 signx = true 1505 } 1506 for i < len(x) { 1507 if x[i] == ' ' { 1508 i++ 1509 continue 1510 } 1511 if x[i] == 'x' && i != 0 && x[i-1] == '0' && y == 0 { 1512 t = true 1513 i++ 1514 continue 1515 } 1516 if t { 1517 if (x[i] >= '0' && x[i] <= '9') || (x[i] >= 'a' && x[i] <= 'f') || (x[i] >= 'A' && x[i] <= 'F') { 1518 xx := uint64(0) 1519 if x[i] >= '0' && x[i] <= '9' { 1520 xx = uint64(x[i] - '0') 1521 } else if x[i] >= 'a' && x[i] <= 'f' { 1522 xx = uint64(x[i]-'a') + 10 1523 } else { 1524 xx = uint64(x[i]-'A') + 10 1525 } 1526 flag = true 1527 z, err = y.Mul64(Decimal64(16)) 1528 if err == nil { 1529 y, err = z.Add64(Decimal64(xx)) 1530 } 1531 if err != nil { 1532 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64.", x) 1533 return 1534 } 1535 } else { 1536 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal64.", x) 1537 return 1538 } 1539 i++ 1540 continue 1541 } 1542 if x[i] == '.' { 1543 if scale == -1 { 1544 scale = 0 1545 } else { 1546 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal64.", x) 1547 return 1548 } 1549 } else if x[i] < '0' || x[i] > '9' { 1550 if x[i] == 'e' { 1551 floatflag = true 1552 i++ 1553 continue 1554 } 1555 if x[i] == '-' && floatflag { 1556 scalesign = true 1557 i++ 1558 continue 1559 } 1560 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal64.", x) 1561 return 1562 } else if !floatflag { 1563 if width == 18 { 1564 if scale == -1 { 1565 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64.", x) 1566 return 1567 } 1568 if x[i] >= '5' { 1569 y, _ = y.Add64(1) 1570 if y1, _ := y.Mod64(10); y1 == 0 { 1571 scale-- 1572 y, _ = y.Scale(-1) 1573 } 1574 } 1575 break 1576 } 1577 flag = true 1578 z = y 1579 y = y*10 + Decimal64(x[i]-'0') 1580 if y>>63 != 0 || y/10 != z { 1581 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64.", x) 1582 return 1583 } 1584 width++ 1585 if scale != -1 { 1586 scale++ 1587 } 1588 } else { 1589 scalecount = scalecount*10 + int32(x[i]-'0') 1590 } 1591 i++ 1592 } 1593 if !flag { 1594 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal64.", x) 1595 return 1596 } 1597 if scale == -1 { 1598 scale = 0 1599 } 1600 if floatflag { 1601 if scalesign { 1602 scalecount = -scalecount 1603 } 1604 scale -= scalecount 1605 if scale < 0 { 1606 y, err = y.Scale(-scale) 1607 scale = 0 1608 if err != nil { 1609 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64.", x) 1610 } 1611 } 1612 } 1613 if signx { 1614 y = y.Minus() 1615 } 1616 return 1617 } 1618 1619 func ParseDecimal64(x string, width, scale int32) (y Decimal64, err error) { 1620 if width > 18 { 1621 width = 18 1622 } 1623 n := int32(0) 1624 y, n, err = Parse64(x) 1625 if err != nil { 1626 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64(%d,%d).", x, width, scale) 1627 return 1628 } 1629 if n > scale { 1630 y, _ = y.Scale(scale - n) 1631 } else { 1632 y, err = y.Scale(scale - n) 1633 if err != nil { 1634 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64(%d,%d).", x, width, scale) 1635 return 1636 } 1637 } 1638 if y.Sign() { 1639 if y.Less(Decimal64(Pow10[width]).Minus()) { 1640 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64(%d,%d).", x, width, scale) 1641 return 1642 } 1643 } else { 1644 if !y.Less(Decimal64(Pow10[width])) { 1645 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal64(%d,%d).", x, width, scale) 1646 return 1647 } 1648 } 1649 return 1650 } 1651 1652 func ParseDecimal64FromByte(x string, width, scale int32) (y Decimal64, err error) { 1653 y = 0 1654 err = nil 1655 n := len(x) 1656 for i := 0; i < n; i++ { 1657 y, err = y.Mul64(256) 1658 if err != nil { 1659 return 1660 } 1661 y, err = y.Add64(Decimal64(x[i])) 1662 if err != nil { 1663 return 1664 } 1665 } 1666 return 1667 } 1668 1669 func Parse128(x string) (y Decimal128, scale int32, err error) { 1670 var z Decimal128 1671 width := 0 1672 t := false 1673 scale = -1 1674 i := 0 1675 flag := false 1676 floatflag := false 1677 scalecount := int32(0) 1678 scalesign := false 1679 signx := false 1680 if x[0] == '-' { 1681 i++ 1682 signx = true 1683 } 1684 for i < len(x) { 1685 if x[i] == ' ' || x[i] == '+' { 1686 i++ 1687 continue 1688 } 1689 if x[i] == 'x' && i != 0 && x[i-1] == '0' && y.B0_63 == 0 && y.B64_127 == 0 { 1690 t = true 1691 i++ 1692 continue 1693 } 1694 if t { 1695 if (x[i] >= '0' && x[i] <= '9') || (x[i] >= 'a' && x[i] <= 'f') || (x[i] >= 'A' && x[i] <= 'F') { 1696 xx := uint64(0) 1697 if x[i] >= '0' && x[i] <= '9' { 1698 xx = uint64(x[i] - '0') 1699 } else if x[i] >= 'a' && x[i] <= 'f' { 1700 xx = uint64(x[i]-'a') + 10 1701 } else { 1702 xx = uint64(x[i]-'A') + 10 1703 } 1704 flag = true 1705 z, err = y.Mul128(Decimal128{16, 0}) 1706 if err == nil { 1707 y, err = z.Add128(Decimal128{xx, 0}) 1708 } 1709 if err != nil { 1710 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128.", x) 1711 return 1712 } 1713 } else { 1714 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal128.", x) 1715 return 1716 } 1717 i++ 1718 continue 1719 } 1720 if x[i] == '.' { 1721 if scale == -1 { 1722 scale = 0 1723 } else { 1724 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal128.", x) 1725 return 1726 } 1727 } else if x[i] < '0' || x[i] > '9' { 1728 if x[i] == 'e' { 1729 floatflag = true 1730 i++ 1731 continue 1732 } 1733 if x[i] == '-' && floatflag { 1734 scalesign = true 1735 i++ 1736 continue 1737 } 1738 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal128.", x) 1739 return 1740 } else if !floatflag { 1741 if width == 38 { 1742 if scale == -1 { 1743 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128.", x) 1744 return 1745 } 1746 if x[i] >= '5' { 1747 y, err = y.Add128(Decimal128{1, 0}) 1748 if y1, _ := y.Mod128(Decimal128{10, 0}); y1.B0_63 == 0 { 1749 scale-- 1750 y, _ = y.Scale(-1) 1751 } 1752 } 1753 break 1754 } 1755 flag = true 1756 z, err = y.Mul128(Decimal128{Pow10[1], 0}) 1757 if err == nil { 1758 y, err = z.Add128(Decimal128{uint64(x[i] - '0'), 0}) 1759 } 1760 if err != nil { 1761 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128.", x) 1762 return 1763 } 1764 width++ 1765 if scale != -1 { 1766 scale++ 1767 } 1768 } else { 1769 scalecount = scalecount*10 + int32(x[i]-'0') 1770 } 1771 i++ 1772 } 1773 if !flag { 1774 err = moerr.NewInvalidInputNoCtx("%s is illegal string, can't be converted to Decimal128.", x) 1775 return 1776 } 1777 if scale == -1 { 1778 scale = 0 1779 } 1780 if floatflag { 1781 if scalesign { 1782 scalecount = -scalecount 1783 } 1784 scale -= scalecount 1785 if scale < 0 { 1786 y, err = y.Scale(-scale) 1787 scale = 0 1788 if err != nil { 1789 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128.", x) 1790 } 1791 } 1792 } 1793 if signx { 1794 y = y.Minus() 1795 } 1796 return 1797 } 1798 1799 func ParseDecimal128(x string, width, scale int32) (y Decimal128, err error) { 1800 if width > 38 { 1801 width = 38 1802 } 1803 n := int32(0) 1804 y, n, err = Parse128(x) 1805 if err != nil { 1806 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128(%d,%d).", x, width, scale) 1807 return 1808 } 1809 if n > scale { 1810 y, _ = y.Scale(scale - n) 1811 } else { 1812 y, err = y.Scale(scale - n) 1813 if err != nil { 1814 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128(%d,%d).", x, width, scale) 1815 return 1816 } 1817 } 1818 var z Decimal128 1819 if width <= 19 { 1820 z = Decimal128{Pow10[width], 0} 1821 } else { 1822 z, _ = Decimal128{Pow10[19], 0}.Mul128(Decimal128{Pow10[width-19], 0}) 1823 } 1824 if y.Sign() { 1825 if y.Less(z.Minus()) { 1826 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128(%d,%d).", x, width, scale) 1827 return 1828 } 1829 } else { 1830 if !y.Less(z) { 1831 err = moerr.NewInvalidInputNoCtx("%s beyond the range, can't be converted to Decimal128(%d,%d).", x, width, scale) 1832 return 1833 } 1834 } 1835 return 1836 } 1837 1838 func ParseDecimal128FromByte(x string, width, scale int32) (y Decimal128, err error) { 1839 y = Decimal128{0, 0} 1840 err = nil 1841 n := len(x) 1842 for i := 0; i < n; i++ { 1843 y, err = y.Mul128(Decimal128{256, 0}) 1844 if err != nil { 1845 return 1846 } 1847 y, err = y.Add128(Decimal128{uint64(x[i]), 0}) 1848 if err != nil { 1849 return 1850 } 1851 } 1852 return 1853 } 1854 1855 func (x Decimal64) Format(scale int32) string { 1856 a := "" 1857 signx := (x >> 63) != 0 1858 if signx { 1859 x = x.Minus() 1860 } 1861 for x != 0 { 1862 a = fmt.Sprintf("%c", x%10+'0') + a 1863 x /= 10 1864 scale-- 1865 if scale == 0 { 1866 a = "." + a 1867 } 1868 } 1869 for scale > 0 { 1870 a = "0" + a 1871 scale-- 1872 if scale == 0 { 1873 a = "." + a 1874 } 1875 } 1876 if scale == 0 { 1877 a = "0" + a 1878 } 1879 if signx { 1880 a = "-" + a 1881 } 1882 return a 1883 } 1884 1885 func (x Decimal128) Format(scale int32) string { 1886 a := "" 1887 signx := x.Sign() 1888 if signx { 1889 x = x.Minus() 1890 } 1891 for x.B64_127 != 0 || x.B0_63 != 0 { 1892 y, _ := x.Mod128(Decimal128{Pow10[1], 0}) 1893 a = fmt.Sprintf("%c", y.B0_63+'0') + a 1894 x, _ = x.Div128(Decimal128{Pow10[1], 0}) 1895 if y.B0_63 >= 5 { 1896 x, _ = x.Sub128(Decimal128{1, 0}) 1897 } 1898 scale-- 1899 if scale == 0 { 1900 a = "." + a 1901 } 1902 } 1903 for scale > 0 { 1904 a = "0" + a 1905 scale-- 1906 if scale == 0 { 1907 a = "." + a 1908 } 1909 } 1910 if scale == 0 { 1911 a = "0" + a 1912 } 1913 if signx { 1914 a = "-" + a 1915 } 1916 return a 1917 } 1918 1919 func (x Decimal256) Format(scale int32) string { 1920 a := "" 1921 return a 1922 } 1923 1924 func (x Decimal64) Ceil(scale1, scale2 int32) Decimal64 { 1925 if x.Sign() { 1926 return x.Minus().Floor(scale1, scale2).Minus() 1927 } 1928 if scale1 > scale2 { 1929 k := scale1 - scale2 1930 if k > 18 { 1931 k = 18 1932 } 1933 y, _, _ := x.Mod(Decimal64(1), k, 0) 1934 if y != 0 { 1935 x, _ = x.Sub64(y) 1936 x, _, _ = x.Add(Decimal64(1), k, 0) 1937 } 1938 } 1939 return x 1940 } 1941 func (x Decimal64) Floor(scale1, scale2 int32) Decimal64 { 1942 if x.Sign() { 1943 return x.Minus().Ceil(scale1, scale2).Minus() 1944 } 1945 if scale1 > scale2 { 1946 k := scale1 - scale2 1947 if k > 18 { 1948 k = 18 1949 } 1950 y, _, _ := x.Mod(Decimal64(1), k, 0) 1951 x, _ = x.Sub64(y) 1952 } 1953 return x 1954 } 1955 1956 func (x Decimal64) Round(scale1, scale2 int32) Decimal64 { 1957 if scale2 >= scale1 { 1958 return x 1959 } 1960 k := scale1 - scale2 1961 if k > 18 { 1962 k = 18 1963 } 1964 x, _ = x.Scale(-k) 1965 x, _ = x.Scale(k) 1966 return x 1967 } 1968 1969 func (x Decimal128) Ceil(scale1, scale2 int32) Decimal128 { 1970 if x.Sign() { 1971 return x.Minus().Floor(scale1, scale2).Minus() 1972 } 1973 if scale1 > scale2 { 1974 k := scale1 - scale2 1975 if k > 38 { 1976 k = 38 1977 } 1978 y, _, _ := x.Mod(Decimal128{1, 0}, k, 0) 1979 if y.B0_63 != 0 || y.B64_127 != 0 { 1980 x, _ = x.Sub128(y) 1981 x, _, _ = x.Add(Decimal128{1, 0}, k, 0) 1982 } 1983 } 1984 return x 1985 } 1986 func (x Decimal128) Floor(scale1, scale2 int32) Decimal128 { 1987 if x.Sign() { 1988 return x.Minus().Ceil(scale1, scale2).Minus() 1989 } 1990 if scale1 > scale2 { 1991 k := scale1 - scale2 1992 if k > 38 { 1993 k = 38 1994 } 1995 y, _, _ := x.Mod(Decimal128{1, 0}, k, 0) 1996 x, _ = x.Sub128(y) 1997 } 1998 return x 1999 } 2000 2001 func (x Decimal128) Round(scale1, scale2 int32) Decimal128 { 2002 if scale2 >= scale1 { 2003 return x 2004 } 2005 k := scale1 - scale2 2006 if k > 38 { 2007 k = 38 2008 } 2009 x, _ = x.Scale(-k) 2010 x, _ = x.Scale(k) 2011 return x 2012 } 2013 2014 // ProtoSize is used by gogoproto. 2015 func (x *Decimal64) ProtoSize() int { 2016 return 8 2017 } 2018 2019 // MarshalToSizedBuffer is used by gogoproto. 2020 func (x *Decimal64) MarshalToSizedBuffer(data []byte) (int, error) { 2021 if len(data) < x.ProtoSize() { 2022 panic("invalid byte slice") 2023 } 2024 binary.BigEndian.PutUint64(data[0:], uint64(*x)) 2025 return 8, nil 2026 } 2027 2028 // MarshalTo is used by gogoproto. 2029 func (x *Decimal64) MarshalTo(data []byte) (int, error) { 2030 size := x.ProtoSize() 2031 return x.MarshalToSizedBuffer(data[:size]) 2032 } 2033 2034 // Marshal is used by gogoproto. 2035 func (x *Decimal64) Marshal() ([]byte, error) { 2036 data := make([]byte, x.ProtoSize()) 2037 n, err := x.MarshalToSizedBuffer(data) 2038 if err != nil { 2039 return nil, err 2040 } 2041 return data[:n], err 2042 } 2043 2044 // Unmarshal is used by gogoproto. 2045 func (x *Decimal64) Unmarshal(data []byte) error { 2046 *x = Decimal64(binary.BigEndian.Uint64(data)) 2047 return nil 2048 } 2049 2050 // ProtoSize is used by gogoproto. 2051 func (x *Decimal128) ProtoSize() int { 2052 return 8 + 8 2053 } 2054 2055 func (x *Decimal128) MarshalToSizedBuffer(data []byte) (int, error) { 2056 if len(data) < x.ProtoSize() { 2057 panic("invalid byte slice") 2058 } 2059 binary.BigEndian.PutUint64(data[0:], x.B0_63) 2060 binary.BigEndian.PutUint64(data[8:], x.B64_127) 2061 return 16, nil 2062 } 2063 2064 // MarshalTo is used by gogoproto. 2065 func (x *Decimal128) MarshalTo(data []byte) (int, error) { 2066 size := x.ProtoSize() 2067 return x.MarshalToSizedBuffer(data[:size]) 2068 } 2069 2070 // Marshal is used by gogoproto. 2071 func (x *Decimal128) Marshal() ([]byte, error) { 2072 data := make([]byte, x.ProtoSize()) 2073 n, err := x.MarshalToSizedBuffer(data) 2074 if err != nil { 2075 return nil, err 2076 } 2077 return data[:n], err 2078 } 2079 2080 // Unmarshal is used by gogoproto. 2081 func (x *Decimal128) Unmarshal(data []byte) error { 2082 if len(data) < x.ProtoSize() { 2083 panic("invalid byte slice") 2084 } 2085 x.B0_63 = binary.BigEndian.Uint64(data[0:]) 2086 x.B64_127 = binary.BigEndian.Uint64(data[8:]) 2087 return nil 2088 }