| 395 | template<typename T> |
| 396 | template<typename RESULT_T> |
| 397 | DecimalValue<RESULT_T> DecimalValue<T>::Multiply(int this_scale, |
| 398 | const DecimalValue& other, int other_scale, int result_precision, int result_scale, |
| 399 | bool round, bool* overflow) const { |
| 400 | // In the non-overflow case, we don't need to adjust by the scale since |
| 401 | // that is already handled by the FE when it computes the result decimal type. |
| 402 | // e.g. 1.23 * .2 (scale 2, scale 1 respectively) is identical to: |
| 403 | // 123 * 2 with a resulting scale 3. We can do the multiply on the unscaled values. |
| 404 | // The result scale in this case is the sum of the input scales. |
| 405 | RESULT_T x = value(); |
| 406 | RESULT_T y = other.value(); |
| 407 | if (x == 0 || y == 0) { |
| 408 | // Handle zero to avoid divide by zero in the overflow check below. |
| 409 | return DecimalValue<RESULT_T>(0); |
| 410 | } |
| 411 | RESULT_T result = 0; |
| 412 | bool needs_int256 = false; |
| 413 | int delta_scale = this_scale + other_scale - result_scale; |
| 414 | if (result_precision == ColumnType::MAX_PRECISION) { |
| 415 | DCHECK_EQ(sizeof(RESULT_T), 16); |
| 416 | int total_leading_zeros = BitUtil::CountLeadingZeros(abs(x)) + |
| 417 | BitUtil::CountLeadingZeros(abs(y)); |
| 418 | // This check is quick, but conservative. In some cases it will indicate that |
| 419 | // converting to 256 bits is necessary, when it's not actually the case. |
| 420 | needs_int256 = total_leading_zeros <= 128; |
| 421 | if (UNLIKELY(needs_int256 && delta_scale == 0)) { |
| 422 | if (LIKELY(abs(x) > MAX_UNSCALED_DECIMAL16 / abs(y))) { |
| 423 | // If the intermediate value does not fit into 128 bits, we indicate overflow |
| 424 | // because the final value would also not fit into 128 bits since delta_scale is |
| 425 | // zero. |
| 426 | *overflow = true; |
| 427 | } else { |
| 428 | // We've verified that the intermediate (and final) value will fit into 128 bits. |
| 429 | needs_int256 = false; |
| 430 | } |
| 431 | } |
| 432 | } |
| 433 | if (UNLIKELY(needs_int256)) { |
| 434 | if (delta_scale == 0) { |
| 435 | DCHECK(*overflow); |
| 436 | } else { |
| 437 | int256_t intermediate_result = ConvertToInt256(x) * ConvertToInt256(y); |
| 438 | intermediate_result = DecimalUtil::ScaleDownAndRound<int256_t>( |
| 439 | intermediate_result, delta_scale, round); |
| 440 | result = ConvertToInt128( |
| 441 | intermediate_result, MAX_UNSCALED_DECIMAL16, overflow); |
| 442 | } |
| 443 | } else { |
| 444 | if (delta_scale == 0) { |
| 445 | result = DecimalUtil::SafeMultiply(x, y, false); |
| 446 | if (UNLIKELY(result_precision == ColumnType::MAX_PRECISION && |
| 447 | abs(result) > MAX_UNSCALED_DECIMAL16)) { |
| 448 | // An overflow is possible here, if, for example, x = (2^64 - 1) and |
| 449 | // y = (2^63 - 1). |
| 450 | *overflow = true; |
| 451 | } |
| 452 | } else if (LIKELY(delta_scale <= 38)) { |
| 453 | result = DecimalUtil::SafeMultiply(x, y, false); |
| 454 | // The largest value that result can have here is (2^64 - 1) * (2^63 - 1), which is |
nothing calls this directly
no test coverage detected