diff options
-rw-r--r-- | Eigen/src/Core/NumTraits.h | 34 | ||||
-rw-r--r-- | Eigen/src/Core/StableNorm.h | 2 | ||||
-rw-r--r-- | unsupported/Eigen/MPRealSupport | 3 |
3 files changed, 38 insertions, 1 deletions
diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h index aebc0c259..4d896a098 100644 --- a/Eigen/src/Core/NumTraits.h +++ b/Eigen/src/Core/NumTraits.h @@ -41,6 +41,34 @@ struct default_digits10_impl<T,false,true> // Integer static int run() { return 0; } }; + +// default implementation of digits(), based on numeric_limits if specialized, +// 0 for integer types, and log2(epsilon()) otherwise. +template< typename T, + bool use_numeric_limits = std::numeric_limits<T>::is_specialized, + bool is_integer = NumTraits<T>::IsInteger> +struct default_digits_impl +{ + static int run() { return std::numeric_limits<T>::digits; } +}; + +template<typename T> +struct default_digits_impl<T,false,false> // Floating point +{ + static int run() { + using std::log; + using std::ceil; + typedef typename NumTraits<T>::Real Real; + return int(ceil(-log(NumTraits<Real>::epsilon())/log(static_cast<Real>(2)))); + } +}; + +template<typename T> +struct default_digits_impl<T,false,true> // Integer +{ + static int run() { return 0; } +}; + } // end namespace internal /** \class NumTraits @@ -119,6 +147,12 @@ template<typename T> struct GenericNumTraits } EIGEN_DEVICE_FUNC + static inline int digits() + { + return internal::default_digits_impl<T>::run(); + } + + EIGEN_DEVICE_FUNC static inline Real dummy_precision() { // make sure to override this for floating-point types diff --git a/Eigen/src/Core/StableNorm.h b/Eigen/src/Core/StableNorm.h index be04ed44d..4ea598ba8 100644 --- a/Eigen/src/Core/StableNorm.h +++ b/Eigen/src/Core/StableNorm.h @@ -74,7 +74,7 @@ blueNorm_impl(const EigenBase<Derived>& _vec) // are used. For any specific computer, each of the assignment // statements can be replaced ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers - it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa + it = NumTraits<RealScalar>::digits(); // number of base-beta digits in mantissa iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent rbig = (std::numeric_limits<RealScalar>::max)(); // largest floating-point number diff --git a/unsupported/Eigen/MPRealSupport b/unsupported/Eigen/MPRealSupport index 7f0b70c63..b770abc4a 100644 --- a/unsupported/Eigen/MPRealSupport +++ b/unsupported/Eigen/MPRealSupport @@ -90,6 +90,9 @@ int main() #ifdef MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS static inline int digits10 (long Precision = mpfr::mpreal::get_default_prec()) { return std::numeric_limits<Real>::digits10(Precision); } static inline int digits10 (const Real& x) { return std::numeric_limits<Real>::digits10(x); } + + static inline int digits () { return std::numeric_limits<Real>::digits(); } + static inline int digits (const Real& x) { return std::numeric_limits<Real>::digits(x); } #endif static inline Real dummy_precision() |