From eb3c92d1ba466a03c990c2408448199054528946 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 5 Aug 2024 10:32:09 +0200 Subject: [PATCH] Init reciprocal_table using constexpr function (#308) --- include/intx/intx.hpp | 31 ++++++++----------------------- test/unittests/test_div.cpp | 6 ++---- 2 files changed, 10 insertions(+), 27 deletions(-) diff --git a/include/intx/intx.hpp b/include/intx/intx.hpp index 8ee14ce8..ba5a6abe 100644 --- a/include/intx/intx.hpp +++ b/include/intx/intx.hpp @@ -5,6 +5,7 @@ #pragma once #include +#include #include #include #include @@ -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 table{}; + for (size_t i = 0; i < table.size(); ++i) + table[i] = static_cast(0x7fd00 / (i + 256)); + return table; +}(); } // namespace internal /// Computes the reciprocal (2^128 - 1) / d - 2^64 for normalized d. @@ -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(d9 - 256)]; const uint64_t d40 = (d >> 24) + 1; const uint64_t v1 = (v0 << 11) - uint32_t(uint32_t{v0 * v0} * d40 >> 40) - 1; diff --git a/test/unittests/test_div.cpp b/test/unittests/test_div.cpp index 7399009f..55e7df15 100644 --- a/test/unittests/test_div.cpp +++ b/test/unittests/test_div.cpp @@ -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); }