Узнайте количество цифр минимального/максимального значения целочисленного типа во время компиляции

Есть ли способ узнать количество цифр минимального/максимального значения целочисленного типа во время компиляции, чтобы его можно было разместить в качестве параметра шаблона?

В идеале будет уже существующее решение, например, в Boost MPL. В противном случае я ищу некоторые указатели для решения с ручным кодом.


person Alex B    schedule 04.03.2010    source источник


Ответы (2)


Это то, что вы ищите?

std::numeric_limits<T>::digits10

Количество цифр (в десятичной системе счисления), которые могут быть представлены без изменений.

person R Samuel Klatchko    schedule 04.03.2010
comment
Обратите внимание, что к количеству цифр значений min / max может потребоваться добавить 1, поскольку ::digits10 указывает только количество цифр без изменений. См. этот вопрос. ::digits (база 2) не имеет этой проблемы. - person Luis Machuca; 15.01.2012

Работает с любым значением, которое вы можете указать в качестве беззнакового длинного аргумента шаблона, в любой базе:

template<unsigned B, unsigned long N>
struct base_digits_detail {
  enum { result = 1 + base_digits_detail<B, N/B>::result };
};
template<unsigned B>
struct base_digits_detail<B, 0> {
private:
  enum { result = 0 };

  template<unsigned, unsigned long>
  friend class base_digits_detail;
};

template<unsigned B, unsigned long N>
struct base_digits {
  enum { result = base_digits_detail<B, N>::result };
};
template<unsigned B>
struct base_digits<B, 0> {
  enum { result = 1 };
};

Контрольная работа

#include <climits>
#include <iostream>
int main() {
  std::cout << base_digits<10, 0>::result << '\n';
  std::cout << base_digits<10, 1>::result << '\n';
  std::cout << base_digits<10, 10>::result << '\n';
  std::cout << base_digits<10, 100>::result << '\n';
  std::cout << base_digits<10, 1000>::result << '\n';
  std::cout << base_digits<10, UINT_MAX>::result << '\n';
  std::cout << '\n';
  std::cout << base_digits<8, 0>::result << '\n';
  std::cout << base_digits<8, 01>::result << '\n';
  std::cout << base_digits<8, 010>::result << '\n';
  std::cout << base_digits<8, 0100>::result << '\n';
  std::cout << base_digits<8, 01000>::result << '\n';
  std::cout << base_digits<8, UINT_MAX>::result << '\n';

  return 0;
}

Вывод

1
1
2
3
4
10

1
1
2
3
4
11
person Community    schedule 04.03.2010