| 103 | template<typename T> |
| 104 | template<typename RESULT_T> |
| 105 | inline typename RESULT_T::underlying_type_t DecimalValue<T>::ToInt(int scale, |
| 106 | bool* overflow) const { |
| 107 | const T divisor = DecimalUtil::GetScaleMultiplier<T>(scale); |
| 108 | const T v = value(); |
| 109 | T result; |
| 110 | if (divisor == 1) { |
| 111 | result = v; |
| 112 | } else { |
| 113 | result = v / divisor; |
| 114 | const T remainder = v % divisor; |
| 115 | // Divisor is always a multiple of 2, so no loss of precision when shifting down |
| 116 | DCHECK(divisor % 2 == 0); // No DCHECK_EQ as this is possibly an int128_t |
| 117 | // N.B. also - no std::abs for int128_t |
| 118 | if (abs(remainder) >= divisor >> 1) { |
| 119 | // Round away from zero. |
| 120 | // Bias at zero must be corrected by sign of dividend. |
| 121 | result += Sign(v); |
| 122 | } |
| 123 | } |
| 124 | *overflow |= |
| 125 | result > std::numeric_limits<typename RESULT_T::underlying_type_t>::max() || |
| 126 | result < std::numeric_limits<typename RESULT_T::underlying_type_t>::min(); |
| 127 | return result; |
| 128 | } |
| 129 | |
| 130 | template<typename T> |
| 131 | inline DecimalValue<T> DecimalValue<T>::ScaleTo(int src_scale, int dst_scale, |