Skip to content

Commit c7aed9d

Browse files
authored
Merge pull request #655 from cppalliance/dec64_div
2 parents 1cd6c70 + e57bff0 commit c7aed9d

File tree

3 files changed

+37
-32
lines changed

3 files changed

+37
-32
lines changed

include/boost/decimal/detail/emulated256.hpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -522,12 +522,18 @@ constexpr uint256_t operator%(uint256_t lhs, std::uint64_t rhs) noexcept
522522
// Get the 256-bit result of multiplication of two 128-bit unsigned integers
523523
constexpr uint256_t umul256_impl(std::uint64_t a_high, std::uint64_t a_low, std::uint64_t b_high, std::uint64_t b_low) noexcept
524524
{
525-
const auto low_product {static_cast<uint128>(a_low) * b_low};
526-
const auto mid_product1 {static_cast<uint128>(a_low) * b_high};
527-
const auto mid_product2 {static_cast<uint128>(a_high) * b_low};
528-
const auto high_product {static_cast<uint128>(a_high) * b_high};
525+
#ifdef BOOST_DECIMAL_HAS_INT128
526+
using unsigned_int128_type = boost::decimal::detail::uint128_t;
527+
#else
528+
using unsigned_int128_type = boost::decimal::detail::uint128;
529+
#endif
530+
531+
const auto low_product {static_cast<unsigned_int128_type>(a_low) * b_low};
532+
const auto mid_product1 {static_cast<unsigned_int128_type>(a_low) * b_high};
533+
const auto mid_product2 {static_cast<unsigned_int128_type>(a_high) * b_low};
534+
const auto high_product {static_cast<unsigned_int128_type>(a_high) * b_high};
529535

530-
uint128 carry {};
536+
std::uint64_t carry {};
531537

532538
const auto mid_combined {mid_product1 + mid_product2};
533539
if (mid_combined < mid_product1)

include/boost/decimal/detail/mul_impl.hpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,10 @@ constexpr auto d64_mul_impl(T1 lhs_sig, std::int32_t lhs_exp, bool lhs_sign,
6969
{
7070
#ifdef BOOST_DECIMAL_HAS_INT128
7171
using unsigned_int128_type = boost::decimal::detail::uint128_t;
72+
constexpr auto comp_value {impl::builtin_128_pow10[31]};
7273
#else
7374
using unsigned_int128_type = boost::decimal::detail::uint128;
75+
constexpr auto comp_value {impl::emulated_128_pow10[31]};
7476
#endif
7577

7678
#ifdef BOOST_DECIMAL_DEBUG
@@ -88,13 +90,10 @@ constexpr auto d64_mul_impl(T1 lhs_sig, std::int32_t lhs_exp, bool lhs_sign,
8890
auto res_sig {static_cast<unsigned_int128_type>(lhs_sig) * static_cast<unsigned_int128_type>(rhs_sig)};
8991
auto res_exp {lhs_exp + rhs_exp};
9092

91-
const auto sig_dig {detail::num_digits(res_sig)};
92-
93-
if (sig_dig > std::numeric_limits<std::uint64_t>::digits10)
94-
{
95-
res_sig /= static_cast<unsigned_int128_type>(detail::pow10(static_cast<std::uint64_t>(sig_dig - std::numeric_limits<std::uint64_t>::digits10)));
96-
res_exp += sig_dig - std::numeric_limits<std::uint64_t>::digits10;
97-
}
93+
const auto sig_dig {res_sig >= comp_value ? 32 : 31};
94+
constexpr auto max_dig {std::numeric_limits<std::uint64_t>::digits10};
95+
res_sig /= detail::pow10(static_cast<unsigned_int128_type>(sig_dig - max_dig));
96+
res_exp += sig_dig - max_dig;
9897

9998
const auto res_sig_64 {static_cast<std::uint64_t>(res_sig)};
10099

include/boost/decimal/detail/power_tables.hpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -96,26 +96,26 @@ static constexpr uint128_t builtin_128_pow10[] = {
9696
uint128_t(100000000000000000),
9797
uint128_t(1000000000000000000),
9898
uint128_t(10000000000000000000ULL),
99-
(uint128_t(7766279631452241920ULL) << 64) | uint128_t(5),
100-
(uint128_t(3875820019684212736ULL) << 64) | uint128_t(54),
101-
(uint128_t(1864712049423024128ULL) << 64) | uint128_t(542),
102-
(uint128_t(200376420520689664ULL) << 64) | uint128_t(5421),
103-
(uint128_t(2003764205206896640ULL) << 64) | uint128_t(54210),
104-
(uint128_t(1590897978359414784ULL) << 64) | uint128_t(542101),
105-
(uint128_t(15908979783594147840ULL) << 64) | uint128_t(5421010),
106-
(uint128_t(11515845246265065472ULL) << 64) | uint128_t(54210108),
107-
(uint128_t(4477988020393345024ULL) << 64) | uint128_t(542101086),
108-
(uint128_t(7886392056514347008ULL) << 64) | uint128_t(5421010862),
109-
(uint128_t(5076944270305263616ULL) << 64) | uint128_t(54210108624),
110-
(uint128_t(13875954555633532928ULL) << 64) | uint128_t(542101086242),
111-
(uint128_t(9632337040368467968ULL) << 64) | uint128_t(5421010862427),
112-
(uint128_t(4089650035136921600ULL) << 64) | uint128_t(54210108624275),
113-
(uint128_t(4003012203950112768ULL) << 64) | uint128_t(542101086242752),
114-
(uint128_t(3136633892082024448ULL) << 64) | uint128_t(5421010862427522),
115-
(uint128_t(12919594847110692864ULL) << 64) | uint128_t(54210108624275221),
116-
(uint128_t(68739955140067328ULL) << 64) | uint128_t(542101086242752217),
117-
(uint128_t(687399551400673280ULL) << 64) | uint128_t(5421010862427522170ULL),
118-
(uint128_t(6873995514006732800ULL) << 64) | uint128_t(17316620476856118468ULL)
99+
uint128_t(10000000000000000000ULL) * uint128_t(10),
100+
uint128_t(10000000000000000000ULL) * uint128_t(100),
101+
uint128_t(10000000000000000000ULL) * uint128_t(1000),
102+
uint128_t(10000000000000000000ULL) * uint128_t(10000),
103+
uint128_t(10000000000000000000ULL) * uint128_t(100000),
104+
uint128_t(10000000000000000000ULL) * uint128_t(1000000),
105+
uint128_t(10000000000000000000ULL) * uint128_t(10000000),
106+
uint128_t(10000000000000000000ULL) * uint128_t(100000000),
107+
uint128_t(10000000000000000000ULL) * uint128_t(1000000000),
108+
uint128_t(10000000000000000000ULL) * uint128_t(10000000000),
109+
uint128_t(10000000000000000000ULL) * uint128_t(100000000000),
110+
uint128_t(10000000000000000000ULL) * uint128_t(1000000000000),
111+
uint128_t(10000000000000000000ULL) * uint128_t(10000000000000),
112+
uint128_t(10000000000000000000ULL) * uint128_t(100000000000000),
113+
uint128_t(10000000000000000000ULL) * uint128_t(1000000000000000),
114+
uint128_t(10000000000000000000ULL) * uint128_t(10000000000000000),
115+
uint128_t(10000000000000000000ULL) * uint128_t(100000000000000000),
116+
uint128_t(10000000000000000000ULL) * uint128_t(1000000000000000000),
117+
uint128_t(10000000000000000000ULL) * uint128_t(10000000000000000000ULL),
118+
uint128_t(10000000000000000000ULL) * uint128_t(10000000000000000000ULL) * uint128_t(10ULL),
119119
};
120120

121121
static_assert(sizeof(builtin_128_pow10) == sizeof(boost::decimal::detail::uint128_t) * 40, "Should have 10^0 to 10^39");

0 commit comments

Comments
 (0)