Обратите внимание, что с плавающей точкой minминимальное положительное значение, где в качестве целого числа minминимальное значение. То же самое касается макросов / констант Си.
Dalle
4
в C99 вы также можете использовать UINT64_MAX и INT64_MAX
Дмитрий Вял
3
@DmitryVyal: Да, вы можете, но это пределы, uint64_tа int64_tне int.
Кит Томпсон,
В C ++ я использовал тот же код, показанный выше: #include <limits>и int imax = std::numeric_limits<int>::max();, но я получаю ошибку Can't resolve struct member 'max'. Любые идеи относительно того, почему это происходит, и как это исправить? Я использую CLion IDE, с CMake и C ++ 11 на Ubuntu 14.04. Я думаю, что это связано с этой проблемой
modulitos
1
Надеюсь, это кому-нибудь поможет, потому что это была ошибка CLion IDE, которую я исправил с помощью последней версии CLion (сборка 138.2344 - CLion находится на этапе программы раннего доступа и поэтому нестабилен)
modulitos
30
Я знаю, что это старый вопрос, но, возможно, кто-то может использовать это решение:
int size =0;// Fill all bits with zero (0)
size =~size;// Negate all bits, thus all bits are set to one (1)
Пока что мы имеем -1 как результат ', пока размер не будет подписан int.
size =(unsignedint)size >>1;// Shift the bits of size one position to the right.
Как говорит Стандарт, биты, которые сдвинуты, равны 1, если переменная подписана, и отрицательны, и 0, если переменная будет без знака или со знаком, и положительна.
Поскольку размер подписан и отрицателен, мы будем сдвигать бит знака, который равен 1, что не очень помогает, поэтому мы приводим к unsigned int, заставляя вместо этого сдвигаться в 0, устанавливая бит знака в 0, оставляя все остальные биты равными 1.
cout << size << endl;// Prints out size which is now set to maximum positive value.
Мы также могли использовать маску и xor, но тогда мы должны были знать точный размер переменной в битах. Смещаясь вперед по битам, нам не нужно знать, сколько битов int имеет на машине или компиляторе, и не нужно включать дополнительные библиотеки.
Я бы не назвал INT_MAX «решением для C». Хотя это старая школа и устарела в C ++.
Пол Томблин
6
Я думаю, что оба ответа C ++. numeric_limits<int>::max()- работает также в шаблонных контекстах, но (по непостижимой для меня причине) не может использоваться как константа времени компиляции. INT_MAX- макрос, довольно бесполезный в функциях шаблона, но может использоваться как константа времени компиляции.
UncleBens
17
Самое смешное, что реализация numeric_limits <int> :: max в msvc выглядит следующим образом: return (INT_MAX);
Никола Смильянич
13
@paul Ссылка на амортизацию, пожалуйста. И угадайте, как numeric_limits реализует max ()? Все верно, верните INT_MAX, по крайней мере, в GCC 4.4.0.
2
@UncleBens: встроенные функции в настоящее время нельзя сводить к константным выражениям.
Георг Фрицше
1
Вот макрос, который я использую, чтобы получить максимальное значение для целых чисел со знаком, которое не зависит от размера используемого целочисленного типа со знаком и для которого gcc -Woverflow не будет жаловаться
#define SIGNED_MAX(x)(~(-1<<(sizeof(x)*8-1)))int a = SIGNED_MAX(a);long b = SIGNED_MAX(b);char c = SIGNED_MAX(c);/* if char is signed for this target */short d = SIGNED_MAX(d);longlong e = SIGNED_MAX(e);
Нет гарантии, что int имеет размер 32 бита, и нет гарантии относительно формата отрицательного целого в памяти. Менее важно то, что нет необходимости заставлять людей смотреть вверх '~'.
Сквики
0
Хорошо, у меня нет ни представителя, чтобы комментировать предыдущий ответ (от Филиппа де Мюйтера), ни повышать его оценку, поэтому новый пример, использующий его определение для SIGNED_MAX, тривиально расширен для неподписанных типов:
// We can use it to define limits based on actual compiler built-in types also: #define INT_MAX SIGNED_MAX(int)// based on the above, we can extend it for unsigned types also:#define UNSIGNED_MAX(x)((SIGNED_MAX(x)<<1)|1)// We reuse SIGNED_MAX#define UINT_MAX UNSIGNED_MAX(unsignedint)// on ARM: 4294967295// then we can have:unsignedint width = UINT_MAX;
В отличие от использования того или иного заголовка, здесь мы используем реальный тип из компилятора.
Что о (1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2)). Это так же, как 2^(8*sizeof(int)-2) - 1 + 2^(8*sizeof(int)-2).
Если sizeof(int) = 4 => 2^(8*4-2) - 1 + 2^(8*4-2) = 2^30 - 1 + 20^30 = (2^32)/2 - 1 [max signed int of 4 bytes].
Вы не можете использовать, 2*(1 << (8*sizeof(int)-2)) - 1потому что он переполнится, но (1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))работает.
int
сlong long int
в Gregories ответ ...-pedantic
) поддерживают его.Ответы:
В C ++:
затем используйте
std::numeric_limits
тип шаблона, который может быть создан с другими типами:В С:
затем используйте
или
источник
min
минимальное положительное значение, где в качестве целого числаmin
минимальное значение. То же самое касается макросов / констант Си.uint64_t
аint64_t
неint
.#include <limits>
иint imax = std::numeric_limits<int>::max();
, но я получаю ошибкуCan't resolve struct member 'max'
. Любые идеи относительно того, почему это происходит, и как это исправить? Я использую CLion IDE, с CMake и C ++ 11 на Ubuntu 14.04. Я думаю, что это связано с этой проблемойЯ знаю, что это старый вопрос, но, возможно, кто-то может использовать это решение:
Пока что мы имеем -1 как результат ', пока размер не будет подписан int.
Как говорит Стандарт, биты, которые сдвинуты, равны 1, если переменная подписана, и отрицательны, и 0, если переменная будет без знака или со знаком, и положительна.
Поскольку размер подписан и отрицателен, мы будем сдвигать бит знака, который равен 1, что не очень помогает, поэтому мы приводим к unsigned int, заставляя вместо этого сдвигаться в 0, устанавливая бит знака в 0, оставляя все остальные биты равными 1.
Мы также могли использовать маску и xor, но тогда мы должны были знать точный размер переменной в битах. Смещаясь вперед по битам, нам не нужно знать, сколько битов int имеет на машине или компиляторе, и не нужно включать дополнительные библиотеки.
источник
cout << "INT_MAX:\t" << (int) ((~((unsigned int) 0)) >> 1) << '\n' << "UINT_MAX:\t" << ~((unsigned int) 0) << endl;
источник
numeric_limits<int>::max()
- работает также в шаблонных контекстах, но (по непостижимой для меня причине) не может использоваться как константа времени компиляции.INT_MAX
- макрос, довольно бесполезный в функциях шаблона, но может использоваться как константа времени компиляции.Вот макрос, который я использую, чтобы получить максимальное значение для целых чисел со знаком, которое не зависит от размера используемого целочисленного типа со знаком и для которого gcc -Woverflow не будет жаловаться
источник
Почему бы не написать кусок кода вроде:
источник
Хорошо, у меня нет ни представителя, чтобы комментировать предыдущий ответ (от Филиппа де Мюйтера), ни повышать его оценку, поэтому новый пример, использующий его определение для SIGNED_MAX, тривиально расширен для неподписанных типов:
В отличие от использования того или иного заголовка, здесь мы используем реальный тип из компилятора.
источник
Это может зависеть от архитектуры, но это работает, по крайней мере, в моей настройке.
источник
Для конкретного максимального значения int я обычно пишу шестнадцатеричное обозначение:
вместо неправильного десятичного значения:
источник
Что о
(1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))
. Это так же, как2^(8*sizeof(int)-2) - 1 + 2^(8*sizeof(int)-2)
.Если
sizeof(int) = 4 => 2^(8*4-2) - 1 + 2^(8*4-2) = 2^30 - 1 + 20^30 = (2^32)/2 - 1 [max signed int of 4 bytes]
.Вы не можете использовать,
2*(1 << (8*sizeof(int)-2)) - 1
потому что он переполнится, но(1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))
работает.источник