Skip to content

Commit

Permalink
Merge pull request #154 from chfast/div_normalize
Browse files Browse the repository at this point in the history
Introduce intx::internal namespace in preparation for header-only library
  • Loading branch information
chfast authored Jun 17, 2020
2 parents 8eaadda + d8210d3 commit cac1c96
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 16 deletions.
21 changes: 11 additions & 10 deletions lib/intx/div.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

namespace intx
{
namespace
namespace internal
{
/// Divides arbitrary long unsigned integer by 64-bit unsigned integer (1 word).
/// @param u The array of a normalized numerator words. It will contain
Expand Down Expand Up @@ -88,7 +88,8 @@ inline uint64_t submul(
return borrow;
}

void udivrem_knuth(uint64_t q[], uint64_t u[], int ulen, const uint64_t d[], int dlen) noexcept
inline void udivrem_knuth(
uint64_t q[], uint64_t u[], int ulen, const uint64_t d[], int dlen) noexcept
{
INTX_REQUIRE(dlen >= 3);
INTX_REQUIRE(ulen >= dlen);
Expand Down Expand Up @@ -129,35 +130,35 @@ void udivrem_knuth(uint64_t q[], uint64_t u[], int ulen, const uint64_t d[], int
}
}

} // namespace
} // namespace internal

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

if (na.num_numerator_words <= na.num_divisor_words)
return {0, u};

if (na.num_divisor_words == 1)
{
auto r =
udivrem_by1(as_words(na.numerator), na.num_numerator_words, as_words(na.divisor)[0]);
const auto r = internal::udivrem_by1(
as_words(na.numerator), na.num_numerator_words, as_words(na.divisor)[0]);
return {na.numerator, r >> na.shift};
}

if (na.num_divisor_words == 2)
{
auto d = as_words(na.divisor);
auto r = udivrem_by2(as_words(na.numerator), na.num_numerator_words, {d[1], d[0]});
const auto d = as_words(na.divisor);
const auto r =
internal::udivrem_by2(as_words(na.numerator), na.num_numerator_words, {d[1], d[0]});
return {na.numerator, r >> na.shift};
}

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

uint<N> q;

udivrem_knuth(
internal::udivrem_knuth(
as_words(q), &un[0], na.num_numerator_words, as_words(na.divisor), na.num_divisor_words);

uint<N> r;
Expand Down
3 changes: 3 additions & 0 deletions lib/intx/div.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

namespace intx
{
namespace internal
{
template <unsigned N>
struct normalized_div_args
{
Expand Down Expand Up @@ -67,4 +69,5 @@ template <typename IntT>
return na;
}

} // namespace internal
} // namespace intx
4 changes: 2 additions & 2 deletions test/benchmarks/bench_div.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ inline uint64_t udiv_by_reciprocal(uint64_t uu, uint64_t du) noexcept
}


template <decltype(normalize<uint512>) NormalizeFn>
template <decltype(internal::normalize<uint512>) NormalizeFn>
static void div_normalize(benchmark::State& state)
{
auto u = uint512{{48882153453, 100324254353}, {4343242153453, 1324254353}};
Expand All @@ -40,7 +40,7 @@ static void div_normalize(benchmark::State& state)
benchmark::DoNotOptimize(x);
}
}
BENCHMARK_TEMPLATE(div_normalize, normalize);
BENCHMARK_TEMPLATE(div_normalize, internal::normalize);

constexpr uint64_t neg(uint64_t x) noexcept
{
Expand Down
8 changes: 4 additions & 4 deletions test/unittests/test_div.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ TEST(div, normalize)
{
uint512 u;
uint512 v = 1;
auto na = normalize(u, v);
auto na = internal::normalize(u, v);
EXPECT_EQ(na.shift, 63u);
EXPECT_EQ(na.num_divisor_words, 1);
EXPECT_EQ(na.num_numerator_words, 0);
Expand All @@ -23,7 +23,7 @@ TEST(div, normalize)

u = uint512{1414, 1313};
v = uint512{12, 1212};
na = normalize(u, v);
na = internal::normalize(u, v);
EXPECT_EQ(na.shift, 60u);
EXPECT_EQ(na.num_divisor_words, 5);
EXPECT_EQ(na.num_numerator_words, 6);
Expand All @@ -33,7 +33,7 @@ TEST(div, normalize)

u = uint512{3} << 510;
v = uint256{0xffffffffffffffff, 1};
na = normalize(u, v);
na = internal::normalize(u, v);
EXPECT_EQ(na.shift, 0u);
EXPECT_EQ(na.num_divisor_words, 3);
EXPECT_EQ(na.num_numerator_words, 8);
Expand All @@ -43,7 +43,7 @@ TEST(div, normalize)

u = uint512{7} << 509;
v = uint256{0x3fffffffffffffff, 1};
na = normalize(u, v);
na = internal::normalize(u, v);
EXPECT_EQ(na.shift, 2u);
EXPECT_EQ(na.num_divisor_words, 3);
EXPECT_EQ(na.num_numerator_words, 9);
Expand Down

0 comments on commit cac1c96

Please sign in to comment.