diff --git a/Eigen/src/Core/IO.h b/Eigen/src/Core/IO.h index 8c794837f..94e00f58b 100644 --- a/Eigen/src/Core/IO.h +++ b/Eigen/src/Core/IO.h @@ -125,31 +125,17 @@ DenseBase::format(const IOFormat& fmt) const namespace internal { -template -struct significant_decimals_default_impl -{ - typedef typename NumTraits::Real RealScalar; - static inline int run() - { - using std::ceil; - using std::log10; - return cast(ceil(-log10(NumTraits::epsilon()))); - } -}; - -template -struct significant_decimals_default_impl -{ - static inline int run() - { - return 0; - } -}; - +// NOTE: This helper is kept for backward compatibility with previous code specializing +// this internal::significant_decimals_impl structure. In the future we should directly +// call digits10() which has been introduced in July 2016 in 3.3. template struct significant_decimals_impl - : significant_decimals_default_impl::IsInteger> -{}; +{ + static inline int run() + { + return NumTraits::digits10(); + } +}; /** \internal * print the matrix \a _m to the output stream \a s using the output format \a fmt */ diff --git a/Eigen/src/Core/NumTraits.h b/Eigen/src/Core/NumTraits.h index 03f64a8e9..a688df504 100644 --- a/Eigen/src/Core/NumTraits.h +++ b/Eigen/src/Core/NumTraits.h @@ -12,6 +12,37 @@ namespace Eigen { +namespace internal { + +// default implementation of digits10(), based on numeric_limits if specialized, +// 0 for integer types, and log10(epsilon()) otherwise. +template< typename T, + bool use_numeric_limits = std::numeric_limits::is_specialized, + bool is_integer = NumTraits::IsInteger> +struct default_digits10_impl +{ + static int run() { return std::numeric_limits::digits10; } +}; + +template +struct default_digits10_impl // Floating point +{ + static int run() { + using std::log10; + using std::ceil; + typedef typename NumTraits::Real Real; + return int(ceil(-log10(NumTraits::epsilon()))); + } +}; + +template +struct default_digits10_impl // Integer +{ + static int run() { return 0; } +}; + +} // end namespace internal + /** \class NumTraits * \ingroup Core_Module * @@ -48,6 +79,9 @@ namespace Eigen { * \li A dummy_precision() function returning a weak epsilon value. It is mainly used as a default * value by the fuzzy comparison operators. * \li highest() and lowest() functions returning the highest and lowest possible values respectively. + * \li digits10() function returning the number of decimal digits that can be represented without change. This is + * the analogue of std::numeric_limits::digits10 + * which is used as the default implementation if specialized. */ template struct GenericNumTraits @@ -93,6 +127,13 @@ template struct GenericNumTraits { return numext::numeric_limits::epsilon(); } + + EIGEN_DEVICE_FUNC + static inline int digits10() + { + return internal::default_digits10_impl::run(); + } + EIGEN_DEVICE_FUNC static inline Real dummy_precision() {