/* ----------------------------------------------------------------------- *//** * * @file Math.hpp * *//* ----------------------------------------------------------------------- */ #ifndef MADLIB_MATH_HPP #define MADLIB_MATH_HPP #include #include namespace madlib { namespace utils { /** * @brief Return the smallest power of 2 that is greater or equal to a number * * This implementation is for integers only. */ template typename boost::enable_if_c::is_integer, T>::type nextPowerOfTwo(T inValue) { if (std::numeric_limits::is_signed && inValue == 0) return 1; inValue--; for (int i = 1; i < std::numeric_limits::digits; i <<= 1) // Note: No overflow can occur in the following line inValue = static_cast(inValue | (inValue >> i)); return static_cast(inValue + 1); } /** * @brief Return if two floating point numbers are almost equal. * * If either of \c inX or \c inY is infinity, the other value has to be infinity * as well in order to be considered equal (irrespective of the units in the * last place). */ template typename boost::enable_if_c::is_integer, bool>::type almostEqual(T inX, T inY, int inULP) { // The machine epsilon has to be scaled to the magnitude of the larger value // and multiplied by the desired precision in ULPs (units in the last place) return ( std::fabs(inX - inY) <= std::numeric_limits::epsilon() * std::max(std::fabs(inX), std::fabs(inY)) * inULP ) || ( boost::math::isinf(inX) && boost::math::isinf(inY) && ((inX < 0) == (inY < 0)) ); } /** * @brief Test if value is negative * * This is the implementation for unsigned T. We use SFINAE because * otherwise the compiler would warn that a comparison < 0 is always false * for unsigned types. */ template inline typename boost::enable_if_c< std::numeric_limits::is_integer && !std::numeric_limits::is_signed, bool >::type isNegative(const T&) { return false; } template inline typename boost::enable_if_c< !std::numeric_limits::is_integer || std::numeric_limits::is_signed, bool >::type isNegative(const T& inValue) { return inValue < static_cast(0); } } // namespace utils } // namespace regress #endif