30#include <jau/test/catch2_ext.hpp>
37TEST_CASE(
"Int Math Test 00",
"[sign][arithmetic][math]" ) {
47 REQUIRE( 1 ==
jau::sign( std::numeric_limits<uint64_t>::max() ) );
48 REQUIRE( 1 ==
jau::sign( std::numeric_limits<int64_t>::max() ) );
49 REQUIRE( -1 ==
jau::sign( std::numeric_limits<int64_t>::min() ) );
51TEST_CASE(
"Int Math Test 01",
"[round][align][arithmetic][math]" ) {
75TEST_CASE(
"Int Math Test 02",
"[abs][arithmetic][math]" ) {
78 REQUIRE( 1_u64 ==
jau::abs( 1_u64) );
79 REQUIRE( std::numeric_limits<uint64_t>::max() ==
jau::abs( std::numeric_limits<uint64_t>::max() ) );
84 REQUIRE( std::numeric_limits<float>::max() ==
jau::abs( std::numeric_limits<float>::max() ) );
85 REQUIRE( std::numeric_limits<float>::min() ==
jau::abs( std::numeric_limits<float>::min() ) );
86 REQUIRE( std::numeric_limits<float>::max() ==
jau::abs( -std::numeric_limits<float>::max() ) );
94 REQUIRE( 1_i64 ==
jau::abs( 1_i64) );
95 REQUIRE( 1_i64 ==
jau::abs(-1_i64) );
99 REQUIRE( std::numeric_limits<int64_t>::max() ==
jau::abs( std::numeric_limits<int64_t>::max() ) );
100 REQUIRE( std::numeric_limits<int64_t>::max() ==
jau::abs( std::numeric_limits<int64_t>::min() ) );
102 REQUIRE( std::numeric_limits<int64_t>::max() ==
jau::ct_abs( std::numeric_limits<int64_t>::max() ) );
105 REQUIRE( std::numeric_limits<int64_t>::max() == std::abs( std::numeric_limits<int64_t>::max() ) );
108 REQUIRE( INT32_MAX ==
jau::abs( INT32_MAX ) );
109 REQUIRE( INT32_MAX ==
jau::abs( INT32_MAX ) );
114 REQUIRE( INT32_MAX == std::abs( INT32_MAX ) );
119TEST_CASE(
"Int Math Test 03a",
"[min][max][clip][arithmetic][math]" ) {
120 REQUIRE( 0 ==
jau::min( 0, INT32_MAX ) );
121 REQUIRE( INT32_MAX ==
jau::max( 0, INT32_MAX ) );
122 REQUIRE( INT32_MAX-1==
jau::min( INT32_MAX-1, INT32_MAX ) );
123 REQUIRE( INT32_MAX ==
jau::max( INT32_MAX-1, INT32_MAX ) );
124 REQUIRE( INT32_MIN ==
jau::min( 0, INT32_MIN ) );
125 REQUIRE( 0 ==
jau::max( 0, INT32_MIN ) );
126 REQUIRE( INT32_MIN ==
jau::min( INT32_MIN+1, INT32_MIN ) );
127 REQUIRE( INT32_MIN+1==
jau::max( INT32_MIN+1, INT32_MIN ) );
129 REQUIRE( -10 ==
jau::clamp( INT32_MIN, -10, 10 ) );
130 REQUIRE( 10 ==
jau::clamp( INT32_MAX, -10, 10 ) );
133TEST_CASE(
"Int Math Test 03b",
"[ct_min][ct_max][clip2][arithmetic][math]" ) {
135 REQUIRE( INT32_MAX ==
jau::ct_max( 0, INT32_MAX ) );
136 REQUIRE( INT32_MAX-1==
jau::ct_min( INT32_MAX-1, INT32_MAX ) );
137 REQUIRE( INT32_MAX ==
jau::ct_max( INT32_MAX-1, INT32_MAX ) );
138 REQUIRE( INT32_MIN+1 ==
jau::ct_min( 0, INT32_MIN+1 ) );
140 REQUIRE( INT32_MIN ==
jau::ct_min( INT32_MIN+1, INT32_MIN ) );
141 REQUIRE( INT32_MIN+1==
jau::ct_max( INT32_MIN+1, INT32_MIN ) );
148TEST_CASE(
"Int Math Test 10",
"[bits][arithmetic][math]" ) {
150 REQUIRE( 0b0000000000000000U ==
ct_masked_merge( 0b0000000000000000U, 0b0000000000000000U, 0b0000000000000000U ) );
151 REQUIRE( 0b1100000000000011U ==
ct_masked_merge( 0b1111111100000000U, 0b1100000000000000U, 0b0000000000000011U ) );
152 REQUIRE( 64_u32 ==
ct_masked_merge( 0b1111111111111111U, 64_u32, 256_u32 ) );
153 REQUIRE( 256_u32 ==
ct_masked_merge( 0b0000000000000000U, 64_u32, 256_u32 ) );
162 REQUIRE( 1u == std::bit_ceil(0u) );
163 REQUIRE( 1u == std::bit_ceil(1u) );
164 REQUIRE( 2u == std::bit_ceil(2u) );
165 REQUIRE( 4u == std::bit_ceil(3u) );
166 REQUIRE(64u == std::bit_ceil(63u) );
175 REQUIRE( 0 ==
ct_bit_count( 0b00000000000000000000000000000000UL ) );
176 REQUIRE( 1 ==
ct_bit_count( 0b00000000000000000000000000000001UL ) );
177 REQUIRE( 1 ==
ct_bit_count( 0b10000000000000000000000000000000UL ) );
178 REQUIRE( 16 ==
ct_bit_count( 0b10101010101010101010101010101010UL ) );
179 REQUIRE( 16 ==
ct_bit_count( 0b01010101010101010101010101010101UL ) );
180 REQUIRE( 32 ==
ct_bit_count( 0b11111111111111111111111111111111UL ) );
182 REQUIRE( 0 ==
bit_count( 0b00000000000000000000000000000000UL ) );
183 REQUIRE( 1 ==
bit_count( 0b00000000000000000000000000000001UL ) );
184 REQUIRE( 1 ==
bit_count( 0b10000000000000000000000000000000UL ) );
185 REQUIRE( 16 ==
bit_count( 0b10101010101010101010101010101010UL ) );
186 REQUIRE( 16 ==
bit_count( 0b01010101010101010101010101010101UL ) );
187 REQUIRE( 32 ==
bit_count( 0b11111111111111111111111111111111UL ) );
190 REQUIRE( 0 ==
high_bit( 0b00000000U ) );
191 REQUIRE( 1 ==
high_bit( 0b00000001U ) );
192 REQUIRE( 2 ==
high_bit( 0b00000010U ) );
193 REQUIRE( 2 ==
high_bit( 0b00000011U ) );
194 REQUIRE( 8 ==
high_bit( 0b11000011U ) );
196 REQUIRE( 64 ==
high_bit( 0b1100001111000011110000111100001111000011110000111100001111000011UL ) );
199TEST_CASE(
"Int Math Test 20",
"[add][sub][overflow][arithmetic][math]" ) {
203 uint64_t a = 1, b = 2, r;
205 REQUIRE( a + b == r );
208 uint64_t a = std::numeric_limits<uint64_t>::max()-2, b = 2, r;
210 REQUIRE( a + b == r );
213 uint64_t a = std::numeric_limits<uint64_t>::max(), b = 2, r;
219 uint64_t a = 2, b = 1, r;
221 REQUIRE( a - b == r );
224 uint64_t a = std::numeric_limits<uint64_t>::min()+2, b = 2, r;
226 REQUIRE( a - b == r );
229 uint64_t a = 1, b = 2, r;
233 uint64_t a = std::numeric_limits<uint64_t>::min(), b = 2, r;
241 int64_t a = 1, b = 2, r;
243 REQUIRE( a + b == r );
246 int64_t a = std::numeric_limits<int64_t>::max()-2, b = 2, r;
248 REQUIRE( a + b == r );
251 int64_t a = std::numeric_limits<int64_t>::max(), b = 2, r;
257 int64_t a = 2, b = 1, r;
259 REQUIRE( a - b == r );
262 int64_t a = std::numeric_limits<int64_t>::min()+2, b = 2, r;
264 REQUIRE( a - b == r );
267 int64_t a = 1, b = 2, r;
269 REQUIRE( a - b == r );
272 uint64_t a = std::numeric_limits<uint64_t>::min(), b = 2, r;
278TEST_CASE(
"Int Math Test 21",
"[mul][overflow][arithmetic][math]" ) {
281 uint64_t a = 1, b = 2, r;
283 REQUIRE( a * b == r );
286 uint64_t a = std::numeric_limits<uint64_t>::max()/2, b = 2, r;
288 REQUIRE( a * b == r );
291 uint64_t a = std::numeric_limits<uint64_t>::max(), b = 2, r;
297 int64_t a = 1, b = 2, r;
299 REQUIRE( a * b == r );
302 int64_t a = std::numeric_limits<int64_t>::max()/2, b = 2, r;
304 REQUIRE( a * b == r );
307 int64_t a = std::numeric_limits<int64_t>::max(), b = 2, r;
314 size_t bitsize = bytesize * 8, r = 0;
315 while ( bitsize >>= 1 ) {
321TEST_CASE(
"Int Math Test 22",
"[log2_byteshift][arithmetic][math]") {
322 for(
size_t bytesz = 1; bytesz < 4096; bytesz<<=1) {
323 size_t bitsz = bytesz*8;
324 size_t l2 = (size_t)std::log2(bitsz);
327 fprintf(stderr,
"bytesz %zu, bitsz %zu: log2 %zu, shift[1 %zu, 2 %zu]\n",
328 bytesz, bitsz, l2, shift1, shift2);
329 REQUIRE( l2 == shift1 );
330 REQUIRE( l2 == shift2 );
constexpr uint32_t ct_bit_count(uint32_t n) noexcept
Returns the number of set bits within given 32bit integer (w/o branching) in O(1) and constant time (...
constexpr T ct_masked_merge(T mask, T a_if_masked, T b_if_unmasked) noexcept
Returns merged a_if_masked bits selected by mask 1 bits and b_if_unmasked bits selected by mask 0 bit...
constexpr T ct_max(const T x, const T y) noexcept
Returns the maximum of two integrals for MIN <= x - y <= MAX (w/o branching) in O(1) and constant tim...
constexpr T ct_min(const T x, const T y) noexcept
Returns the minimum of two integrals for MIN <= x - y <= MAX (w/o branching) in O(1) and constant tim...
constexpr T ct_clamp(const T x, const T min_val, const T max_val) noexcept
Returns constrained integral value to lie between given min- and maximum value for MIN <= x - y <= MA...
constexpr T ct_abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/o branching) in O(1) and constant time (CT),...
consteval_cxx20 bool is_cxx20() noexcept
Returns true if compiled with >= C++20.
constexpr size_t log2_byteshift(const size_t bytesize) noexcept
Returns log2(bytesize*8), e.g.
constexpr bool mul_overflow(const T a, const T b, T &res) noexcept
Integer overflow aware multiplication returning true if overflow occurred, otherwise false having the...
constexpr T clamp(const T x, const T min_val, const T max_val) noexcept
Returns constrained integral value to lie between given min- and maximum value (w/ branching) in O(1)...
constexpr T round_up(const T n, const U align_to)
Round up w/ branching in O(1)
constexpr nsize_t high_bit(T x)
Return the index of the highest set bit w/ branching (loop) in O(n/2).
constexpr bool sub_overflow(const T a, const T b, T &res) noexcept
Integer overflow aware subtraction returning true if overflow occurred, otherwise false having the re...
constexpr bool add_overflow(const T a, const T b, T &res) noexcept
Integer overflow aware addition returning true if overflow occurred, otherwise false having the resul...
constexpr T round_down(T n, U align_to)
Round down w/ branching in O(1)
constexpr T bit_ceil(const T n) noexcept
If the given n is not is_power_of_2() return next_power_of_2(), otherwise return n unchanged.
constexpr int sign(const T x) noexcept
Returns the value of the sign function (w/o branching ?) in O(1).
constexpr bool is_power_of_2(const T x) noexcept
Power of 2 test in O(1), i.e.
constexpr T min(const T x, const T y) noexcept
Returns the minimum of two integrals (w/ branching) in O(1)
constexpr T max(const T x, const T y) noexcept
Returns the maximum of two integrals (w/ branching) in O(1)
constexpr size_t bit_count(T n) noexcept
Returns the number of set bits within given unsigned integral.
constexpr T abs(const T x) noexcept
Returns the absolute value of an arithmetic number (w/ branching) in O(1)
__pack(...): Produces MSVC, clang and gcc compatible lead-in and -out macros.
static constexpr size_t log2_byteshift2(const size_t bytesize) noexcept
TEST_CASE("Int Math Test 00", "[sign][arithmetic][math]")