Как узнать, сколько чисел представимо данным типом, кроме std::pow(2., sizeof(type)*8)
?
С++11
std::numeric_limits<type>::max()
не уверен, но можно опробовать так:
unsigned int ui = 0;
int i = (x - 1)/2
вообще вроде в библиотеке limits.h
есть INT_MAX
Нашёл:
std::numeric_limits<std::make_unsigned<my_type>::type>::max()
Для целочисленных типов кол-во различных вариантов может быть получено путём вычитания минимально возможного значения из максимально возможного и добавления единицы, т.е.:
std::numeric_limits<T>::max() - std::numeric_limits<T>::min() + 1;
Но здесь стоит учесть тот момент, что для типов с рангом >= int
мы получим переполнение и результат в виде нуля. Чтобы этого не произошло нужно привести первый аргумент к некоторому максимально возможному целому типу. Назовём его пока BigInt
.
static_cast<BigInt>(std::numeric_limits<T>::max()) - std::numeric_limits<T>::min() + 1;
Этот подход увеличит кол-во типов, для которых можно вызывать код, но переполнение всё равно будет возникать для ситуаций, когда sizeof(T) == sizeof(BigInt)
. И этого не избежать, т.к. любой тип будет иметь представление для нуля, а стало быть кол-во возможных вариантов как минимум на единицу больше, чем максимально представимое этим типом число.
Для демонстрации в качестве BigInt
я выбрал нестандартный, но имеющийся в различных компиляторах тип __int128_t
:
template <class T>
auto range() {
return static_cast<__int128_t>(std::numeric_limits<T>::max()) - std::numeric_limits<T>::min() + 1;
}
Проверка (код для вывода значения типа __int128_t
заимствован из ответа James Kanze, т.к. готовых решений компиляторами не предоставляется):
#include <cstdint>
#include <limits>
#include <iostream>
std::ostream&
operator<<( std::ostream& dest, __int128_t value )
{
std::ostream::sentry s( dest );
if ( s ) {
__uint128_t tmp = value < 0 ? -value : value;
char buffer[ 128 ];
char* d = std::end( buffer );
do
{
-- d;
*d = "0123456789"[ tmp % 10 ];
tmp /= 10;
} while ( tmp != 0 );
if ( value < 0 ) {
-- d;
*d = '-';
}
int len = std::end( buffer ) - d;
if ( dest.rdbuf()->sputn( d, len ) != len ) {
dest.setstate( std::ios_base::badbit );
}
}
return dest;
}
template <class T>
auto range() {
return static_cast<__int128_t>(std::numeric_limits<T>::max()) - std::numeric_limits<T>::min() + 1;
}
int main() {
std::cout << range<int>() << "\n"
<< range<unsigned>() << "\n"
<< range<long>() << "\n"
<< range<char>() << "\n"
<< range<short>() << "\n"
<< range<unsigned long long>() << "\n"
<< range<bool>() << "\n";
}
Возможный вывод:
4294967296
4294967296
18446744073709551616
256
65536
18446744073709551616
2
Вариант с std::make_unsigned
, предложенный в другом ответе, не будет работать для типа bool
, т.к. он не имеет возможности быть знаковым или беззнаковым.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Пишу dll на C++Можно ли помещать в ней функцию в namespace? Если да, то какой в этом профит, кроме решения проблемы неуникальности имен и как вызывать...
Как создать именованный канал в Windows, чтобы можно было читать из него и записывать данные в него без каких-либо логинов и паролей с компьютеров...
В файле записаны числа, нужно их считать, построить дерево поискаПосле этого сбалансировать дерево, выполнив RR поворот