@@ -145,6 +145,32 @@ class DecimalUtilOp {
145145 return std::min (x_lz, y_lz);
146146 }
147147
148+ template <class T , typename = std::enable_if_t <std::is_same_v<T, int64_t >>>
149+ FOLLY_ALWAYS_INLINE static int64_t
150+ multiply (int64_t a, int64_t b, bool * overflow) {
151+ int64_t value;
152+ *overflow = __builtin_mul_overflow (a, b, &value);
153+ if (!*overflow && value >= velox::DecimalUtil::kShortDecimalMin &&
154+ value <= velox::DecimalUtil::kShortDecimalMax ) {
155+ return value;
156+ }
157+ *overflow = true ;
158+ return -1 ;
159+ }
160+
161+ template <class T , typename = std::enable_if_t <std::is_same_v<T, int128_t >>>
162+ FOLLY_ALWAYS_INLINE static int128_t
163+ multiply (int128_t a, int128_t b, bool * overflow) {
164+ int128_t value;
165+ *overflow = __builtin_mul_overflow (a, b, &value);
166+ if (!*overflow && value >= velox::DecimalUtil::kLongDecimalMin &&
167+ value <= velox::DecimalUtil::kLongDecimalMax ) {
168+ return value;
169+ }
170+ *overflow = true ;
171+ return -1 ;
172+ }
173+
148174 template <typename R, typename A, typename B>
149175 inline static R divideWithRoundUp (
150176 R& r,
@@ -175,8 +201,10 @@ class DecimalUtilOp {
175201 }
176202 auto bitsRequiredAfterScaling = maxBitsRequiredAfterScaling<A>(a, aRescale);
177203 if (bitsRequiredAfterScaling <= 127 ) {
178- unsignedDividendRescaled = checkedMultiply<R>(
179- unsignedDividendRescaled, R (DecimalUtil::kPowersOfTen [aRescale]));
204+ unsignedDividendRescaled = multiply<R, A>(
205+ unsignedDividendRescaled,
206+ R (DecimalUtil::kPowersOfTen [aRescale]),
207+ overflow);
180208 if (*overflow) {
181209 return R (-1 );
182210 }
0 commit comments