mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-11-27 06:30:28 +08:00
Fixes #2703 by adding max_digits10 function
This commit is contained in:
parent
9995c3da6f
commit
ba1cb6e45e
@ -117,13 +117,13 @@ namespace internal {
|
||||
|
||||
// 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.
|
||||
// call max_digits10().
|
||||
template<typename Scalar>
|
||||
struct significant_decimals_impl
|
||||
{
|
||||
static inline int run()
|
||||
{
|
||||
return NumTraits<Scalar>::digits10();
|
||||
return NumTraits<Scalar>::max_digits10();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -16,37 +16,6 @@ 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<T>::is_specialized,
|
||||
bool is_integer = NumTraits<T>::IsInteger>
|
||||
struct default_digits10_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() { return std::numeric_limits<T>::digits10; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct default_digits10_impl<T,false,false> // Floating point
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() {
|
||||
using std::log10;
|
||||
using std::ceil;
|
||||
typedef typename NumTraits<T>::Real Real;
|
||||
return int(ceil(-log10(NumTraits<Real>::epsilon())));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct default_digits10_impl<T,false,true> // Integer
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
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,
|
||||
@ -77,6 +46,66 @@ struct default_digits_impl<T,false,true> // Integer
|
||||
static int run() { return 0; }
|
||||
};
|
||||
|
||||
// default implementation of digits10(), based on numeric_limits if specialized,
|
||||
// 0 for integer types, and floor((digits()-1)*log10(2)) otherwise.
|
||||
template< typename T,
|
||||
bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
|
||||
bool is_integer = NumTraits<T>::IsInteger>
|
||||
struct default_digits10_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() { return std::numeric_limits<T>::digits10; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct default_digits10_impl<T,false,false> // Floating point
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() {
|
||||
using std::log10;
|
||||
using std::floor;
|
||||
typedef typename NumTraits<T>::Real Real;
|
||||
return int(floor((internal::default_digits_impl<Real>::run()-1)*log10(2)));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct default_digits10_impl<T,false,true> // Integer
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() { return 0; }
|
||||
};
|
||||
|
||||
// default implementation of max_digits10(), based on numeric_limits if specialized,
|
||||
// 0 for integer types, and log10(2) * digits() + 1 otherwise.
|
||||
template< typename T,
|
||||
bool use_numeric_limits = std::numeric_limits<T>::is_specialized,
|
||||
bool is_integer = NumTraits<T>::IsInteger>
|
||||
struct default_max_digits10_impl
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() { return std::numeric_limits<T>::max_digits10; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct default_max_digits10_impl<T,false,false> // Floating point
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() {
|
||||
using std::log10;
|
||||
using std::ceil;
|
||||
typedef typename NumTraits<T>::Real Real;
|
||||
return int(ceil(internal::default_digits_impl<Real>::run()*log10(2)+1));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct default_max_digits10_impl<T,false,true> // Integer
|
||||
{
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static int run() { return 0; }
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
namespace numext {
|
||||
@ -143,6 +172,9 @@ EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC Tgt bit_cast(const Src& src) {
|
||||
* \li digits10() function returning the number of decimal digits that can be represented without change. This is
|
||||
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/digits10">std::numeric_limits<T>::digits10</a>
|
||||
* which is used as the default implementation if specialized.
|
||||
* \li max_digits10() function returning the number of decimal digits required to uniquely represent all distinct values of the type. This is
|
||||
* the analogue of <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10">std::numeric_limits<T>::max_digits10</a>
|
||||
* which is used as the default implementation if specialized.
|
||||
* \li min_exponent() and max_exponent() functions returning the highest and lowest possible values, respectively,
|
||||
* such that the radix raised to the power exponent-1 is a normalized floating-point number. These are equivalent to
|
||||
* <a href="http://en.cppreference.com/w/cpp/types/numeric_limits/min_exponent">std::numeric_limits<T>::min_exponent</a>/
|
||||
@ -180,6 +212,12 @@ template<typename T> struct GenericNumTraits
|
||||
return internal::default_digits10_impl<T>::run();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static inline int max_digits10()
|
||||
{
|
||||
return internal::default_max_digits10_impl<T>::run();
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static inline int digits()
|
||||
{
|
||||
@ -282,6 +320,8 @@ template<typename Real_> struct NumTraits<std::complex<Real_> >
|
||||
static inline Real dummy_precision() { return NumTraits<Real>::dummy_precision(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static inline int digits10() { return NumTraits<Real>::digits10(); }
|
||||
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR
|
||||
static inline int max_digits10() { return NumTraits<Real>::max_digits10(); }
|
||||
};
|
||||
|
||||
template<typename Scalar, int Rows, int Cols, int Options, int MaxRows, int MaxCols>
|
||||
@ -312,6 +352,8 @@ struct NumTraits<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
|
||||
EIGEN_CONSTEXPR
|
||||
static inline int digits10() { return NumTraits<Scalar>::digits10(); }
|
||||
EIGEN_CONSTEXPR
|
||||
static inline int max_digits10() { return NumTraits<Scalar>::max_digits10(); }
|
||||
};
|
||||
|
||||
template<> struct NumTraits<std::string>
|
||||
@ -326,8 +368,10 @@ template<> struct NumTraits<std::string>
|
||||
|
||||
EIGEN_CONSTEXPR
|
||||
static inline int digits10() { return 0; }
|
||||
EIGEN_CONSTEXPR
|
||||
static inline int max_digits10() { return 0; }
|
||||
|
||||
private:
|
||||
private:
|
||||
static inline std::string epsilon();
|
||||
static inline std::string dummy_precision();
|
||||
static inline std::string lowest();
|
||||
|
@ -76,6 +76,7 @@ namespace Eigen {
|
||||
static inline Real epsilon() { return 0; }
|
||||
static inline Real dummy_precision() { return 0; }
|
||||
static inline int digits10() { return 0; }
|
||||
static inline int max_digits10() { return 0; }
|
||||
|
||||
enum {
|
||||
IsInteger = 0,
|
||||
|
@ -156,6 +156,7 @@ EIGEN_DECLARE_TEST(boostmultiprec)
|
||||
std::cout << "NumTraits<Real>::lowest() = " << NumTraits<Real>::lowest() << std::endl;
|
||||
std::cout << "NumTraits<Real>::highest() = " << NumTraits<Real>::highest() << std::endl;
|
||||
std::cout << "NumTraits<Real>::digits10() = " << NumTraits<Real>::digits10() << std::endl;
|
||||
std::cout << "NumTraits<Real>::max_digits10() = " << NumTraits<Real>::max_digits10() << std::endl;
|
||||
|
||||
// check stream output
|
||||
{
|
||||
|
@ -20,6 +20,7 @@ EIGEN_DECLARE_TEST(mpreal_support)
|
||||
std::cerr << "highest = " << NumTraits<mpreal>::highest() << "\n";
|
||||
std::cerr << "lowest = " << NumTraits<mpreal>::lowest() << "\n";
|
||||
std::cerr << "digits10 = " << NumTraits<mpreal>::digits10() << "\n";
|
||||
std::cerr << "max_digits10 = " << NumTraits<mpreal>::max_digits10() << "\n";
|
||||
|
||||
for(int i = 0; i < g_repeat; i++) {
|
||||
int s = Eigen::internal::random<int>(1,100);
|
||||
|
Loading…
Reference in New Issue
Block a user