25#ifndef JAU_INT_MATH_HPP_
26#define JAU_INT_MATH_HPP_
56 template<std::
integral T>
57 constexpr bool is_zero(
const T& a)
noexcept {
68 template<std::
integral T>
69 constexpr bool equals(
const T& a,
const T& b)
noexcept {
81 template<std::
integral T>
82 constexpr bool equals(
const T& a,
const T& b,
const T& allowed_deviation)
noexcept {
83 return std::abs(a - b) <= allowed_deviation;
95 template<jau::req::
unsigned_
integral T, jau::req::
unsigned_
integral U>
96 constexpr T
round_up(
const T n,
const U align_to) {
97 assert(align_to != 0);
100 return n + (align_to - (n % align_to));
115 template<jau::req::
unsigned_
integral T, jau::req::
unsigned_
integral U>
117 return align_to == 0 ? n : (n - (n % align_to));
133 template<jau::req::
unsigned_
integral T>
136 return std::has_single_bit(x);
138 return x && 0 == (x & (x - 1));
151 if ( bytesize < 256 ) {
152 switch ( bytesize ) {
168 size_t bitsize = (bytesize * 8) >> 11, r = 11;
169 while ( bitsize >>= 1 ) {
185 template<jau::req::
unsigned_
integral T>
188 return std::bit_ceil(n);
202 template<jau::req::
unsigned_
integral T>
205 for (
nsize_t s = (CHAR_BIT *
sizeof(T)) >> 1; s > 0; s >>= 1 ) {
219 template<jau::req::
unsigned_
integral T>
221 return (
size_t)std::popcount(n);
229 #if defined __has_builtin && __has_builtin(__builtin_add_overflow)
240 #if defined __has_builtin && __has_builtin(__builtin_sub_overflow)
251 #if defined __has_builtin && __has_builtin(__builtin_mul_overflow)
272 template<std::
integral T>
275 return __builtin_add_overflow(a, b, &res);
279 if ( (b >= 0 && a > std::numeric_limits<T>::max() - b) ||
280 (b < 0 && a < std::numeric_limits<T>::min() - b) ) {
303 template<std::
integral T>
306 return __builtin_sub_overflow(a, b, &res);
310 if ( (b < 0 && a > std::numeric_limits<T>::max() + b) ||
311 (b >= 0 && a < std::numeric_limits<T>::min() + b) ) {
334 template<std::
integral T>
337 return __builtin_mul_overflow(a, b, &res);
340 if ( (b > 0 &&
abs(a) > std::numeric_limits<T>::max() / b) ||
341 (b < 0 &&
abs(a) > std::numeric_limits<T>::min() / b) ) {
369 template<jau::req::
signed_
integral T>
370 constexpr T
gcd(T a, T b)
noexcept {
381 template<jau::req::
unsigned_
integral T>
382 constexpr T
gcd(T a, T b)
noexcept {
400 template<std::
integral T>
401 constexpr bool lcm_overflow(
const T a,
const T b, T& result)
noexcept {
402 const T _gcd =
gcd<T>(a, b);
435 template<std::
integral T>
436 constexpr size_t digits10(
const T x,
const snsize_t x_sign,
const bool sign_is_digit =
true) noexcept {
441 return 1 +
static_cast<size_t>(std::log10<T>(
invert_sign<T>(x))) + (sign_is_digit ? 1 : 0);
443 return 1 +
static_cast<size_t>(std::log10<T>(x));
461 template<std::
integral T>
462 constexpr size_t digits10(
const T x,
const bool sign_is_digit =
true) noexcept {
475 template<jau::req::
unsigned_
integral T>
482 return 1 +
static_cast<nsize_t>(std::log2<T>(x));
484 return 1 +
static_cast<nsize_t>(std::log10<T>(x));
486 return 1 +
static_cast<nsize_t>(std::log10<T>(x) / std::log10<T>(radix));
constexpr uint32_t ct_next_power_of_2(uint32_t n) noexcept
Returns the next higher power of 2 of given unsigned 32-bit n (w/o branching) in O(1) and constant ti...
constexpr T ct_is_zero(T x)
Returns ~0 (2-complement) if arg is zero, otherwise 0 (w/o branching) in O(1) and constant time (CT).
consteval_cxx20 bool is_cxx20() noexcept
Returns true if compiled with >= C++20.
#define consteval_cxx20
consteval qualifier replacement for C++20 consteval.
constexpr bool equals(const T &a, const T &b, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if both values are equal, i.e.
constexpr bool is_zero(const T &a, const T &epsilon=std::numeric_limits< T >::epsilon()) noexcept
Returns true if the given value is less than epsilon, w/ epsilon > 0.
sint_bytes_t< sizeof(long int)> snsize_t
Natural 'ssize_t' alternative using int<XX>_t with xx = sizeof(long int)*8 as its natural sized type,...
constexpr size_t log2_byteshift(const size_t bytesize) noexcept
Returns log2(bytesize*8), e.g.
constexpr bool lcm_overflow(const T a, const T b, T &result) noexcept
Integer overflow aware calculation of least common multiple (LCM) following Euclid's algorithm from E...
constexpr T invert_sign(const T x) noexcept
Safely inverts the sign of an arithmetic number w/ branching in O(1)
consteval_cxx20 bool has_builtin_mul_overflow() noexcept
Query whether __builtin_mul_overflow is available via __has_builtin(__builtin_mul_overflow).
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 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 size_t digits(const T x, const nsize_t radix) noexcept
Returns the number of digits of the given unsigned integral value number and the given radix.
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 size_t digits10(const T x, const snsize_t x_sign, const bool sign_is_digit=true) noexcept
Returns the number of decimal digits of the given integral value number using std::log10<T>().
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 T gcd(T a, T b) noexcept
Returns the greatest common divisor (GCD) of the two given integer values following Euclid's algorith...
constexpr int sign(const T x) noexcept
Returns the value of the sign function (w/o branching ?) in O(1).
uint_bytes_t< sizeof(unsigned long int)> nsize_t
Natural 'size_t' alternative using uint<XX>_t with xx = sizeof(unsigned long int)*8 as its natural si...
consteval_cxx20 bool has_builtin_add_overflow() noexcept
Query whether __builtin_add_overflow is available via __has_builtin(__builtin_add_overflow).
consteval_cxx20 bool has_builtin_sub_overflow() noexcept
Query whether __builtin_sub_overflow is available via __has_builtin(__builtin_sub_overflow).
constexpr bool is_power_of_2(const T x) noexcept
Power of 2 test in O(1), i.e.
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.