| 551 | template<typename T> |
| 552 | template<typename RESULT_T> |
| 553 | inline DecimalValue<RESULT_T> DecimalValue<T>::Mod(int this_scale, |
| 554 | const DecimalValue& other, int other_scale, int result_precision, int result_scale, |
| 555 | bool round, bool* is_nan, bool* overflow) const { |
| 556 | DCHECK_EQ(result_scale, std::max(this_scale, other_scale)); |
| 557 | *is_nan = other.value() == 0; |
| 558 | if (UNLIKELY(*is_nan)) return DecimalValue<RESULT_T>(); |
| 559 | |
| 560 | RESULT_T result; |
| 561 | switch (sizeof(RESULT_T)) { |
| 562 | case 4: { |
| 563 | int64_t x, y; |
| 564 | AdjustToSameScale(*this, this_scale, other, other_scale, result_precision, &x, &y); |
| 565 | DCHECK(abs(x % y) <= MAX_UNSCALED_DECIMAL4); |
| 566 | result = x % y; |
| 567 | break; |
| 568 | } |
| 569 | case 8: { |
| 570 | if (detail::MinLeadingZeros<RESULT_T>( |
| 571 | value(), this_scale, other.value(), other_scale) >= 2) { |
| 572 | int64_t x, y; |
| 573 | AdjustToSameScale(*this, this_scale, other, other_scale, |
| 574 | result_precision, &x, &y); |
| 575 | DCHECK(abs(x % y) <= MAX_UNSCALED_DECIMAL8); |
| 576 | result = x % y; |
| 577 | } else { |
| 578 | int128_t x, y; |
| 579 | AdjustToSameScale(*this, this_scale, other, other_scale, |
| 580 | result_precision, &x, &y); |
| 581 | DCHECK(abs(x % y) <= MAX_UNSCALED_DECIMAL8); |
| 582 | result = x % y; |
| 583 | } |
| 584 | break; |
| 585 | } |
| 586 | case 16: { |
| 587 | if (detail::MinLeadingZeros<RESULT_T>( |
| 588 | value(), this_scale, other.value(), other_scale) >= 2) { |
| 589 | int128_t x, y; |
| 590 | AdjustToSameScale(*this, this_scale, other, other_scale, |
| 591 | result_precision, &x, &y); |
| 592 | DCHECK(abs(x % y) <= MAX_UNSCALED_DECIMAL16); |
| 593 | result = x % y; |
| 594 | } else { |
| 595 | int256_t x_256 = ConvertToInt256(value()); |
| 596 | int256_t y_256 = ConvertToInt256(other.value()); |
| 597 | if (this_scale < other_scale) { |
| 598 | x_256 *= DecimalUtil::GetScaleMultiplier<int256_t>(other_scale - this_scale); |
| 599 | } else { |
| 600 | y_256 *= DecimalUtil::GetScaleMultiplier<int256_t>(this_scale - other_scale); |
| 601 | } |
| 602 | int256_t intermediate_result = x_256 % y_256; |
| 603 | bool ovf = false; |
| 604 | result = ConvertToInt128(intermediate_result, |
| 605 | MAX_UNSCALED_DECIMAL16, &ovf); |
| 606 | DCHECK(!ovf); |
| 607 | } |
| 608 | break; |
| 609 | } |
| 610 | default: { |
nothing calls this directly
no test coverage detected