diff --git a/cpp/src/arrow/util/basic_decimal.cc b/cpp/src/arrow/util/basic_decimal.cc index ccf7af82c0827..e1ca749e0c27d 100644 --- a/cpp/src/arrow/util/basic_decimal.cc +++ b/cpp/src/arrow/util/basic_decimal.cc @@ -1186,8 +1186,11 @@ DecimalStatus BasicDecimalAnyWidth::Divide(const BasicDecimalAnyWidth& di bool dividen_was_negative = Sign() == -1; bool divisor_was_negative = divisor.Sign() == -1; - *result = value / divisor.value; - *remainder = value % divisor.value; + BasicDecimalAnyWidth dividen_abs = BasicDecimalAnyWidth::Abs(*this); + BasicDecimalAnyWidth divisor_abs = BasicDecimalAnyWidth::Abs(divisor); + + *result = dividen_abs.value / divisor_abs.value; + *remainder = dividen_abs.value % divisor_abs.value; FixDivisionSigns(result, remainder, dividen_was_negative, divisor_was_negative); return DecimalStatus::kSuccess; diff --git a/cpp/src/arrow/util/basic_decimal.h b/cpp/src/arrow/util/basic_decimal.h index 6fc8b6f53d573..9e62fb35fa53b 100644 --- a/cpp/src/arrow/util/basic_decimal.h +++ b/cpp/src/arrow/util/basic_decimal.h @@ -339,6 +339,7 @@ ARROW_EXPORT BasicDecimal256 operator/(const BasicDecimal256& left, template class ARROW_EXPORT BasicDecimalAnyWidth { public: + static constexpr int bit_width = width; using ValueType = typename IntTypes::signed_type; /// \brief Empty constructor creates a BasicDecimal with a value of 0. constexpr BasicDecimalAnyWidth() noexcept : value(0) {} diff --git a/cpp/src/arrow/util/decimal_test.cc b/cpp/src/arrow/util/decimal_test.cc index 2065472a99385..4e46522eef2b2 100644 --- a/cpp/src/arrow/util/decimal_test.cc +++ b/cpp/src/arrow/util/decimal_test.cc @@ -1729,20 +1729,20 @@ const std::vector>> TYPED_TEST(DecimalAnyWidthTest, BinaryOperations) { using ValueType = typename arrow::DecimalAnyWidthTest_BinaryOperations_Test< gtest_TypeParam_>::TypeParam::ValueType; - using ArrowValueType = typename arrow::CTypeTraits::ArrowType; auto DecimalFns = DecimalAnyWidthBinaryParams::value; auto NumericFns = DecimalAnyWidthBinaryParams::value; for (size_t i = 0; i < DecimalFns.size(); i++) { - for (auto x : GetRandomNumbers(8)) { - for (auto y : GetRandomNumbers(8)) { + for (ValueType x : GetRandomNumbers(8)) { + for (ValueType y : GetRandomNumbers(8)) { TypeParam d1(x), d2(y); - auto result = DecimalFns[i].second(d1, d2); - auto reference = static_cast(NumericFns[i].second(x, y)); + TypeParam result = DecimalFns[i].second(d1, d2); + ValueType reference = static_cast(NumericFns[i].second(x, y)); ASSERT_EQ(reference, result) - << d1 << " " << DecimalFns[i].first << " " << d2 << " " - << " != " << result; + << "(" << x << " " << DecimalFns[i].first << " " << y << " = " << reference + << ") != (" << d1 << " " << DecimalFns[i].first << " " << d2 << " = " + << result << ")"; } } }