Skip to content

Commit

Permalink
fix multiply half round up
Browse files Browse the repository at this point in the history
  • Loading branch information
jinchengchenghh committed Mar 30, 2023
1 parent 9026ec3 commit db21063
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions velox/functions/prestosql/DecimalArithmetic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ class Addition {
const uint8_t aScale,
const uint8_t bPrecision,
const uint8_t bScale) {
return {std::min(
return {
std::min(
38,
std::max(aPrecision - aScale, bPrecision - bScale) +
std::max(aScale, bScale) + 1),
Expand Down Expand Up @@ -366,7 +367,7 @@ class Multiply {
int256_t aLarge = a.unscaledValue();
int256_t blarge = b.unscaledValue();
int256_t reslarge = aLarge * blarge;
reslarge = reslarge / DecimalUtil::kPowersOfTen[deltaScale];
reslarge = ReduceScaleBy(reslarge, deltaScale);
auto res = R::convert(reslarge, overflow);
if (!*overflow) {
r = res;
Expand Down Expand Up @@ -412,6 +413,26 @@ class Multiply {
return Addition::adjustPrecisionScale(
aPrecision + bPrecision + 1, aScale + bScale);
}

private:
// derive from Arrow
inline static int256_t ReduceScaleBy(int256_t in, int32_t reduceBy) {
if (reduceBy == 0) {
// nothing to do.
return in;
}

int256_t divisor = DecimalUtil::kPowersOfTen[reduceBy];
DCHECK_GT(divisor, 0);
DCHECK_EQ(divisor % 2, 0); // multiple of 10.
auto result = in / divisor;
auto remainder = in % divisor;
// round up (same as BasicDecimal128::ReduceScaleBy)
if (abs(remainder) >= (divisor >> 1)) {
result += (in > 0 ? 1 : -1);
}
return result;
}
};

class Divide {
Expand Down

0 comments on commit db21063

Please sign in to comment.