Library: extend text coverage for util::floorwrap

These two helpers ''just happen to work'' in the full domain, and also for unsigned types.
I can not recall that I actually was aware of that, but it's nice.

Thus add some test cases to cover the bounds of the domain
This commit is contained in:
Fischlurch 2026-09-14 16:34:15 +02:00
parent 00941095c3
commit 32fbfa7909

View file

@ -30,7 +30,7 @@
using ::Test; using ::Test;
using util::isnil; using util::isnil;
using util::_Fmt; using util::_Fmt;
using std::integral;
namespace util { namespace util {
namespace test { namespace test {
@ -42,6 +42,13 @@ namespace test {
const uint NUM_ELMS_PERFORMANCE_TEST = 50000000; const uint NUM_ELMS_PERFORMANCE_TEST = 50000000;
const uint NUMBER_LIMIT = 1 << 30; const uint NUMBER_LIMIT = 1 << 30;
template<typename NUM>
constexpr NUM _MAX = std::numeric_limits<NUM>::max();
template<typename NUM>
constexpr NUM _MIN = std::numeric_limits<NUM>::lowest();
typedef std::vector<int> VecI; typedef std::vector<int> VecI;
VecI VecI
@ -108,7 +115,7 @@ namespace test {
{ {
seedRand(); seedRand();
verifyBehaviour (); verifyBehaviour();
verifyIntegerTypes<int>(); verifyIntegerTypes<int>();
verifyIntegerTypes<long>(); verifyIntegerTypes<long>();
@ -116,6 +123,8 @@ namespace test {
verifyIntegerTypes<int64_t>(); verifyIntegerTypes<int64_t>();
verifyIntegerTypes<llong>(); verifyIntegerTypes<llong>();
verifyBounds();
if (not isnil (arg)) if (not isnil (arg))
runPerformanceTest(); runPerformanceTest();
} }
@ -154,7 +163,7 @@ namespace test {
template<typename I> template<typename I>
void void
verifyIntegerTypes () verifyIntegerTypes()
{ {
I n,d,expectedRes; I n,d,expectedRes;
@ -168,6 +177,46 @@ namespace test {
} }
void
verifyBounds()
{
auto verify = []<integral I>(I num, I den, I expect_quot, I expect_rem)
{
auto res = floorwrap (num,den);
CHECK (res.quot == expect_quot, "quotient mismatch");
CHECK (res.rem == expect_rem , "remainder mismatch");
CHECK (res.quot == floordiv (num,den), "floordiv diverges");
};
//----- num | den | quotient | remainder
verify (_MAX<int>, 1, _MAX<int> , 0);
verify (_MAX<int>, 2, _MAX<int>/2 , 1);
verify (_MAX<int>, 5, _MAX<int>/5 , 2);
verify (_MIN<int>, 1, _MIN<int> , 0);
verify (_MIN<int>, 2, _MIN<int>/2 , 0);
verify (_MIN<int>, 5, _MIN<int>/5 -1, 2); // _MIN<int> ≡ -2147483648 /5 ≡ -429496729 -1 step ≡ -429496730 · 5 ≡ -2147483650 ⟹ Δ = +2
verify (_MAX<int>,-1, -_MAX<int> , 0);
verify (_MAX<int>,-2, -_MAX<int>/2 -1,-1);
verify (_MAX<int>,-5, -_MAX<int>/5 -1,-3); // Δ ≡ -3 here since -_MAX<int> ≡ _MIN<int> + 1
verify (_MAX<uint>, 1u, _MAX<uint> ,0u);
verify (_MAX<uint>, 2u, _MAX<uint>/2 ,1u);
verify (_MAX<uint>, 5u, _MAX<uint>/5 ,0u);
verify (_MIN<int64_t>, int64_t(1), _MIN<int64_t> , int64_t(0));
verify (_MIN<int64_t>, int64_t(2), _MIN<int64_t>/2 , int64_t(0));
verify (_MIN<int64_t>, int64_t(5), _MIN<int64_t>/5 -1, int64_t(2)); // 2^63 / 5 ≡ 1844674407370955161.6 ; 1844674407370955162 · 5 ⟹ Δ = +2
verify (_MIN<int8_t>, int8_t(1), int8_t(-128) , int8_t(0));
verify (_MIN<int8_t>, int8_t(2), int8_t(-64 ) , int8_t(0));
verify (_MIN<int8_t>, int8_t(5), int8_t(-26 ) , int8_t(2)); // 2^7 / 5 ≡ 25.6 ; 26 · 5 ≡ 130 ⟹ Δ = +2
verify (_MAX<int8_t>, int8_t(5), int8_t( 25 ) , int8_t(2)); // (2^7-1) / 5 ≡ 25.4 ; 25 · 5 ≡ 125 ⟹ Δ = +2
}
/** @test timing measurements to compare implementation details. /** @test timing measurements to compare implementation details.
* This test uses a sequence of random integers, where the values * This test uses a sequence of random integers, where the values