108 lines
2.4 KiB
C++
108 lines
2.4 KiB
C++
// vi:set ft=cpp: -*- Mode: C++ -*-
|
|
/*
|
|
* (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
|
|
* economic rights: Technische Universität Dresden (Germany)
|
|
*
|
|
* License: see LICENSE.spdx (in this directory or the directories above)
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
namespace cxx { namespace arith {
|
|
|
|
/**
|
|
* Divides two integers, and rounds the result to the next largest integer if
|
|
* the division yields a remainder.
|
|
*
|
|
* Examples:
|
|
* 6 / 3 = 2
|
|
* 7 / 3 = 3
|
|
* -7 / 3 = -2
|
|
*
|
|
* \param n Numerator
|
|
* \param d Denominator
|
|
*
|
|
* \return ceil(n / d)
|
|
*/
|
|
template<typename N, typename D>
|
|
constexpr N
|
|
div_ceil(N const &n, D const &d)
|
|
{
|
|
// Since C++11 the "quotient is truncated towards zero (fractional part is
|
|
// discarded)". Thus a negative quotient is already ceiled, whereas a
|
|
// positive quotient is floored. Furthermore, since C++11 the sign of the
|
|
// % operator is no longer implementation defined, thus we can use n % d to
|
|
// detect if the quotient is positive (n % d >= 0) and was truncated (n % d !=
|
|
// 0). In that case, we add one to round to the next largest integer.
|
|
return n / d + (n % d > 0);
|
|
}
|
|
|
|
/**
|
|
* Computes the binary logarithm of the given number at compile time.
|
|
*
|
|
* \param val Number whose logarithm to compute, must be greater than zero.
|
|
*
|
|
* \return The binary logarithm of `val`.
|
|
*/
|
|
template< unsigned long V >
|
|
struct Ld
|
|
{
|
|
enum { value = Ld<V / 2>::value + 1 };
|
|
};
|
|
|
|
template<>
|
|
struct Ld<0>
|
|
{
|
|
enum { value = ~0UL };
|
|
};
|
|
|
|
template<>
|
|
struct Ld<1>
|
|
{
|
|
enum { value = 0 };
|
|
};
|
|
|
|
/**
|
|
* Computes the binary logarithm of the given number.
|
|
*
|
|
* \param val Number whose logarithm to compute, must be greater than zero.
|
|
*
|
|
* \return The binary logarithm of `val`.
|
|
*/
|
|
constexpr unsigned
|
|
log2u(unsigned val)
|
|
{
|
|
return 8 * sizeof(val) - __builtin_clz(val) - 1;
|
|
}
|
|
|
|
/// \copydoc log2u(unsigned)
|
|
constexpr unsigned
|
|
log2u(unsigned long val)
|
|
{
|
|
return 8 * sizeof(val) - __builtin_clzl(val) - 1;
|
|
}
|
|
|
|
/// \copydoc log2u(unsigned)
|
|
constexpr unsigned
|
|
log2u(unsigned long long val)
|
|
{
|
|
return 8 * sizeof(val) - __builtin_clzll(val) - 1;
|
|
}
|
|
|
|
/**
|
|
* Computes the ceiling of the binary logarithm of the given number.
|
|
*
|
|
* \param val Number whose ceiling of the logarithm to compute, must be
|
|
* greater than zero.
|
|
*
|
|
* \return The ceiling of the binary logarithm of `val`.
|
|
*/
|
|
template<typename T>
|
|
constexpr unsigned
|
|
log2u_ceil(T val)
|
|
{
|
|
return val == 1 ? 0 : log2u(val - 1) + 1;
|
|
}
|
|
|
|
}}
|