Add is_pow2, round_up

This commit is contained in:
Danny Robson 2011-08-29 14:31:22 +10:00
parent 306f852fc7
commit 380d51d05a
2 changed files with 58 additions and 0 deletions

View File

@ -19,9 +19,11 @@
#include "maths.hpp"
#include "enable_if.hpp"
#include "float.hpp"
#include <cmath>
#include <type_traits>
template <typename T>
@ -33,6 +35,19 @@ template double pow2(double);
template int pow2( int);
template <typename T>
bool
is_pow2 (T value) {
typedef typename enable_if<std::is_integral<T>::value, bool>::type return_type;
return (return_type)(value && !(value & (value - 1)));
}
template bool is_pow2 (uint8_t);
template bool is_pow2 (uint16_t);
template bool is_pow2 (uint32_t);
template bool is_pow2 (uint64_t);
template <typename T>
double
rootsquare (T a, T b)
@ -54,3 +69,31 @@ almost_equal (const double &a, const double &b)
{ return ieee_double::almost_equal (a, b); }
template <typename T>
typename enable_if<std::is_integral<T>::value, T>::type
round_up (T value, T align) {
check_hard (align > 1);
return (value + align - 1) / align;
}
template <typename T>
T
round_pow2 (T value) {
typedef typename enable_if<std::is_integral<T>::value, T>::type return_type;
--value;
for (unsigned i = 1; i < sizeof (T) * 8; i <<= 1) {
value |= value >> i;
}
++value;
return (return_type)value;
}
template uint8_t round_pow2 (uint8_t);
template uint16_t round_pow2 (uint16_t);
template uint32_t round_pow2 (uint32_t);
template uint64_t round_pow2 (uint64_t);

View File

@ -28,11 +28,26 @@ T
pow2 (T value) pure;
template <typename T>
bool
is_pow2 (T value) pure;
template <typename T>
double
rootsquare (T a, T b) pure;
template <typename T>
T
round_up (T value, T align) pure;
template <typename T>
T
round_pow2 (T value) pure;
/**
* Check if two floating point numbers are approximately equal. Returns true
* if the difference is less than a percentage of each individual value.