Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/boost/decimal/detail/mul_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ BOOST_DECIMAL_CUDA_CONSTEXPR auto d128_mul_impl(const T1& lhs_sig_in, const U1 l
auto res_sig {detail::umul256(lhs_sig_in, rhs_sig_in)};
auto res_exp_mut {static_cast<typename ReturnType::biased_exponent_type>(lhs_exp_in + rhs_exp_in)};
const auto sig_dig {detail::num_digits(res_sig)};
const auto digit_delta {sig_dig - std::numeric_limits<sig_type>::digits10};
const auto digit_delta {sig_dig - detail::precision_v<ReturnType>};
if (BOOST_DECIMAL_LIKELY(digit_delta > 0))
{
auto biased_exp {res_exp_mut + detail::bias_v<ReturnType>};
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ run github_issue_1459_toward_zero.cpp
run github_issue_1467.cpp ;
run github_issue_1473.cpp ;
run github_issue_1476.cpp ;
run github_issue_1482.cpp ;

run link_1.cpp link_2.cpp link_3.cpp ;
run quick.cpp ;
Expand Down
54 changes: 54 additions & 0 deletions test/github_issue_1482.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2026 Shen-Ta Hsieh
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt

#include <boost/decimal.hpp>
#include <boost/core/lightweight_test.hpp>

using namespace boost::decimal;
using namespace boost::decimal::literals;

// The exponents sum to below -6142, and the product of the short operands has 36 to 38
// digits. The multiply must round it to 34 digits before it packs the result.
int main()
{
BOOST_TEST_EQ(34e-6168_DL * 6304777571276319608815211782449451e-6_DL, 2143624374233948666997172006032813e-6172_DL);
BOOST_TEST_EQ(99e-6150_DL * 1234567890123456789012345678901234e-20_DL, 1222222211222222221122222222112222e-6168_DL);
BOOST_TEST_EQ(9999e-6160_DL * 9999999999999999999999999999999999e-10_DL, 9998999999999999999999999999999999e-6166_DL);
// A tie goes to the even neighbour
BOOST_TEST_EQ(5e-6160_DL * 2000000000000000000000000000000001e-10_DL, 1000000000000000000000000000000000e-6169_DL);

// A 38-digit product far below the smallest subnormal rounds to zero
BOOST_TEST_EQ(9999999999999999999e-3112_DL * 9999999999999999999e-3113_DL, 0_DL);

// fesetround has an effect only with the detection of constant evaluation
#ifndef BOOST_DECIMAL_NO_CONSTEVAL_DETECTION
// A positive product goes up, a negative product goes toward zero
fesetround(rounding_mode::fe_dec_upward);
BOOST_TEST_EQ(34e-6168_DL * 6304777571276319608815211782449451e-6_DL, 2143624374233948666997172006032814e-6172_DL);
BOOST_TEST_EQ(9999e-6160_DL * 9999999999999999999999999999999999e-10_DL, 9999000000000000000000000000000000e-6166_DL);
BOOST_TEST_EQ(-5e-6160_DL * 2000000000000000000000000000000001e-10_DL, -1000000000000000000000000000000000e-6169_DL);

// A negative product goes down, a positive product goes toward zero
fesetround(rounding_mode::fe_dec_downward);
BOOST_TEST_EQ(-34e-6168_DL * 6304777571276319608815211782449451e-6_DL, -2143624374233948666997172006032814e-6172_DL);
BOOST_TEST_EQ(-9999e-6160_DL * 9999999999999999999999999999999999e-10_DL, -9999000000000000000000000000000000e-6166_DL);
BOOST_TEST_EQ(99e-6150_DL * 1234567890123456789012345678901234e-20_DL, 1222222211222222221122222222112221e-6168_DL);

// A tie goes away from zero
fesetround(rounding_mode::fe_dec_to_nearest_from_zero);
BOOST_TEST_EQ(5e-6160_DL * 2000000000000000000000000000000001e-10_DL, 1000000000000000000000000000000001e-6169_DL);
BOOST_TEST_EQ(-5e-6160_DL * 2000000000000000000000000000000001e-10_DL, -1000000000000000000000000000000001e-6169_DL);
BOOST_TEST_EQ(99e-6150_DL * 1234567890123456789012345678901234e-20_DL, 1222222211222222221122222222112222e-6168_DL);

// All products go toward zero
fesetround(rounding_mode::fe_dec_toward_zero);
BOOST_TEST_EQ(99e-6150_DL * 1234567890123456789012345678901234e-20_DL, 1222222211222222221122222222112221e-6168_DL);
BOOST_TEST_EQ(-9999e-6160_DL * 9999999999999999999999999999999999e-10_DL, -9998999999999999999999999999999999e-6166_DL);
BOOST_TEST_EQ(5e-6160_DL * 2000000000000000000000000000000001e-10_DL, 1000000000000000000000000000000000e-6169_DL);

fesetround(rounding_mode::fe_dec_to_nearest);
#endif

return boost::report_errors();
}
Loading