From 24679866fea7635d75b238385ea174bf34c82d94 Mon Sep 17 00:00:00 2001 From: Chip Hogg Date: Tue, 12 Nov 2024 16:23:39 -0500 Subject: [PATCH] Be more careful with `as_int` The old version worked fine, but it felt a little sketchy the way we were handling implicit conversion from a wrapped-around unsigned to a smaller signed type. (Note that if the signed type had been bigger, we would silently get the wrong answer!) --- au/code/au/utility/probable_primes.hh | 4 +++- au/code/au/utility/test/probable_primes_test.cc | 5 +++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/au/code/au/utility/probable_primes.hh b/au/code/au/utility/probable_primes.hh index 49710538..99d6d284 100644 --- a/au/code/au/utility/probable_primes.hh +++ b/au/code/au/utility/probable_primes.hh @@ -189,7 +189,9 @@ struct LucasDParameter { uint64_t mag = 5u; bool is_neg = false; - friend constexpr int as_int(const LucasDParameter &D) { return D.is_neg ? -D.mag : D.mag; } + friend constexpr int as_int(const LucasDParameter &D) { + return bool_sign(!D.is_neg) * static_cast(D.mag); + } friend constexpr void increment(LucasDParameter &D) { D.mag += 2u; D.is_neg = !D.is_neg; diff --git a/au/code/au/utility/test/probable_primes_test.cc b/au/code/au/utility/test/probable_primes_test.cc index f16a14f4..9f167be9 100644 --- a/au/code/au/utility/test/probable_primes_test.cc +++ b/au/code/au/utility/test/probable_primes_test.cc @@ -222,6 +222,11 @@ std::vector strong_lucas_pseudoprimes() { 231703u, 243629u, 253259u, 268349u, 288919u, 313499u, 324899u}; } +TEST(LucasDParameter, CanConvertToInt) { + EXPECT_EQ(as_int(LucasDParameter{5u, false}), 5); + EXPECT_EQ(as_int(LucasDParameter{7u, true}), -7); +} + TEST(StrongLucas, AllPrimeNumbersAreProbablyPrime) { const auto primes = first_n_primes<3'000u>(); for (const auto &p : primes) {