Skip to content

Commit

Permalink
div: Make udivrem() a proper template
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast committed Jun 13, 2019
1 parent 232b2c1 commit 9386419
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 24 deletions.
2 changes: 1 addition & 1 deletion include/intx/int128.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@ inline std::string to_string(uint<N> x, int base = 10)
while (x != 0)
{
// TODO: Use constexpr udivrem_1?
const auto res = udivrem(x, base);
const auto res = udivrem(x, uint<N>{base});
const auto d = int(res.rem);
const auto c = d < 10 ? '0' + d : 'a' + d - 10;
s.push_back(char(c));
Expand Down
4 changes: 2 additions & 2 deletions include/intx/intx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,8 +730,8 @@ inline typename std::enable_if<sizeof(Word) < sizeof(Int), unsigned>::type count
return h != 0 ? h + (num_words / 2) : l;
}

div_result<uint256> udivrem(const uint256& u, const uint256& v) noexcept;
div_result<uint512> udivrem(const uint512& x, const uint512& y) noexcept;
template <unsigned N>
div_result<uint<N>> udivrem(const uint<N>& u, const uint<N>& v) noexcept;

template <unsigned N>
constexpr div_result<uint<N>> sdivrem(const uint<N>& u, const uint<N>& v) noexcept
Expand Down
28 changes: 7 additions & 21 deletions lib/intx/div.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,6 @@ namespace intx
{
namespace
{
union uint512_words64
{
using word_type = uint64_t;

const uint512 number;
word_type words[uint512::num_words];

constexpr explicit uint512_words64(uint512 x = {}) noexcept : number{x} {}

word_type& operator[](size_t index) { return words[index]; }
};

/// Divides arbitrary long unsigned integer by 64-bit unsigned integer (1 word).
/// @param u The array of a normalized numerator words. It will contain the quotient after
/// execution.
Expand Down Expand Up @@ -151,13 +139,8 @@ void udivrem_knuth(uint64_t q[], uint64_t un[], int m, const uint64_t vn[], int

} // namespace

div_result<uint256> udivrem(const uint256& u, const uint256& v) noexcept
{
auto x = udivrem(uint512{u}, uint512{v});
return {x.quot.lo, x.rem.lo};
}

div_result<uint512> udivrem(const uint512& u, const uint512& v) noexcept
template <unsigned N>
div_result<uint<N>> udivrem(const uint<N>& u, const uint<N>& v) noexcept
{
auto na = normalize(u, v);

Expand All @@ -183,8 +166,8 @@ div_result<uint512> udivrem(const uint512& u, const uint512& v) noexcept

auto un = as_words(na.numerator); // Will be modified.

uint512 q;
uint512 r;
uint<N> q;
uint<N> r;
auto rw = as_words(r);

udivrem_knuth(as_words(q), &un[0], m, as_words(na.denominator), n);
Expand All @@ -195,4 +178,7 @@ div_result<uint512> udivrem(const uint512& u, const uint512& v) noexcept
return {q, r};
}

template div_result<uint256> udivrem(const uint256& u, const uint256& v) noexcept;
template div_result<uint512> udivrem(const uint512& u, const uint512& v) noexcept;

} // namespace intx

0 comments on commit 9386419

Please sign in to comment.