diff options
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/MathFunctions.h | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index e29733c13..7c67ffdf7 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -476,31 +476,35 @@ inline NewType cast(const OldType& x) * Implementation of round * ****************************************************************************/ +template<typename Scalar> +struct round_impl +{ + EIGEN_DEVICE_FUNC + static inline Scalar run(const Scalar& x) + { + EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL) #if EIGEN_HAS_CXX11_MATH - template<typename Scalar> - struct round_impl { - EIGEN_DEVICE_FUNC - static inline Scalar run(const Scalar& x) - { - EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL) - EIGEN_USING_STD(round); + EIGEN_USING_STD(round); + return Scalar(round(x)); +#elif EIGEN_HAS_C99_MATH + if (is_same<Scalar, float>::value) { + return Scalar(::roundf(x)); + } else { return Scalar(round(x)); } - }; #else - template<typename Scalar> - struct round_impl - { - EIGEN_DEVICE_FUNC - static inline Scalar run(const Scalar& x) - { - EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL) - EIGEN_USING_STD(floor); - EIGEN_USING_STD(ceil); - return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5)); + EIGEN_USING_STD(floor); + EIGEN_USING_STD(ceil); + // If not enough precision to resolve a decimal at all, return the input. + // Otherwise, adding 0.5 can trigger an increment by 1. + const Scalar limit = Scalar(1ull << (NumTraits<Scalar>::digits() - 1)); + if (x >= limit || x <= -limit) { + return x; } - }; + return (x > Scalar(0)) ? Scalar(floor(x + Scalar(0.5))) : Scalar(ceil(x - Scalar(0.5))); #endif + } +}; template<typename Scalar> struct round_retval |