Skip to content

Commit

Permalink
Init reciprocal_table using constexpr function (#308)
Browse files Browse the repository at this point in the history
  • Loading branch information
chfast authored Aug 5, 2024
1 parent 6bae23e commit eb3c92d
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 27 deletions.
31 changes: 8 additions & 23 deletions include/intx/intx.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#pragma once

#include <algorithm>
#include <array>
#include <bit>
#include <cassert>
#include <climits>
Expand Down Expand Up @@ -601,29 +602,13 @@ struct div_result

namespace internal
{
inline constexpr uint16_t reciprocal_table_item(uint8_t d9) noexcept
{
return uint16_t(0x7fd00 / (0x100 | d9));
}

#define REPEAT4(x) \
reciprocal_table_item((x) + 0), reciprocal_table_item((x) + 1), \
reciprocal_table_item((x) + 2), reciprocal_table_item((x) + 3)

#define REPEAT32(x) \
REPEAT4((x) + 4 * 0), REPEAT4((x) + 4 * 1), REPEAT4((x) + 4 * 2), REPEAT4((x) + 4 * 3), \
REPEAT4((x) + 4 * 4), REPEAT4((x) + 4 * 5), REPEAT4((x) + 4 * 6), REPEAT4((x) + 4 * 7)

#define REPEAT256() \
REPEAT32(32 * 0), REPEAT32(32 * 1), REPEAT32(32 * 2), REPEAT32(32 * 3), REPEAT32(32 * 4), \
REPEAT32(32 * 5), REPEAT32(32 * 6), REPEAT32(32 * 7)

/// Reciprocal lookup table.
constexpr uint16_t reciprocal_table[] = {REPEAT256()};

#undef REPEAT4
#undef REPEAT32
#undef REPEAT256
constexpr auto reciprocal_table = []() noexcept {
std::array<uint16_t, 256> table{};
for (size_t i = 0; i < table.size(); ++i)
table[i] = static_cast<uint16_t>(0x7fd00 / (i + 256));
return table;
}();
} // namespace internal

/// Computes the reciprocal (2^128 - 1) / d - 2^64 for normalized d.
Expand All @@ -634,7 +619,7 @@ inline constexpr uint64_t reciprocal_2by1(uint64_t d) noexcept
INTX_REQUIRE(d & 0x8000000000000000); // Must be normalized.

const uint64_t d9 = d >> 55;
const uint32_t v0 = internal::reciprocal_table[d9 - 256];
const uint32_t v0 = internal::reciprocal_table[static_cast<size_t>(d9 - 256)];

const uint64_t d40 = (d >> 24) + 1;
const uint64_t v1 = (v0 << 11) - uint32_t(uint32_t{v0 * v0} * d40 >> 40) - 1;
Expand Down
6 changes: 2 additions & 4 deletions test/unittests/test_div.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -488,8 +488,6 @@ TEST(div, reciprocal_3by2)

TEST(div, reciprocal_table)
{
uint8_t d = 0;
EXPECT_EQ(internal::reciprocal_table_item(d), 2045);
d = 0xff;
EXPECT_EQ(internal::reciprocal_table_item(d), 1024);
EXPECT_EQ(internal::reciprocal_table[0], 2045);
EXPECT_EQ(internal::reciprocal_table[0xff], 1024);
}

0 comments on commit eb3c92d

Please sign in to comment.