maksymalna wartość int

177

Czy istnieje kod do znalezienia maksymalnej wartości liczby całkowitej (zgodnie z kompilatorem) w C / C ++, jak Integer.MaxValuefunkcja w java?

d3vdpro
źródło
1
czy istnieje sposób, aby znaleźć maksymalną wartość long long int?
d3vdpro
Wystarczy wymienić intze long long intw Gregories odpowiedź ...
Georg Fritzsche
1
poza tym, że long long nie jest częścią C ++
@Neil, prawda, jego C99 - ale VC i GCC (bez -pedantic) go obsługują.
Georg Fritzsche,

Odpowiedzi:

323

W C ++:

#include <limits>

następnie użyj

int imin = std::numeric_limits<int>::min(); // minimum value
int imax = std::numeric_limits<int>::max();

std::numeric_limits jest typem szablonu, którego instancję można utworzyć z innymi typami:

float fmin = std::numeric_limits<float>::min(); // minimum positive value
float fmax = std::numeric_limits<float>::max();

W C:

#include <limits.h>

następnie użyj

int imin = INT_MIN; // minimum value
int imax = INT_MAX;

lub

#include <float.h>

float fmin = FLT_MIN;  // minimum positive value
double dmin = DBL_MIN; // minimum positive value

float fmax = FLT_MAX;
double dmax = DBL_MAX;
Gregory Pakosz
źródło
13
Zauważ, że zmiennoprzecinkowe minsą minimalną wartością dodatnią , gdzie jako liczby całkowite minsą wartością minimalną. To samo dotyczy makr / stałych języka C.
dalle
4
w C99 można również użyć UINT64_MAX i INT64_MAX
Dmitry Vyal
3
@DmitryVyal: Tak, możesz, ale to są ograniczenia uint64_ti int64_tnie int.
Keith Thompson,
W C ++ użyłem tego samego kodu, co powyżej: #include <limits>i int imax = std::numeric_limits<int>::max();, ale pojawia się błąd Can't resolve struct member 'max'. Jakieś pomysły, dlaczego tak się dzieje i jak to naprawić? Używam CLion IDE z CMake i C ++ 11 na Ubuntu 14.04. Myślę, że jest to związane z tą kwestią
modulitos
1
Mam nadzieję, że to komuś pomoże, ponieważ był to błąd CLion IDE, który naprawiłem, używając najnowszego CLion (kompilacja 138.2344 - CLion jest w fazie programu wczesnego dostępu, a zatem jest niestabilny)
modulitos
30

Wiem, że to stare pytanie, ale może ktoś może skorzystać z takiego rozwiązania:

int size = 0; // Fill all bits with zero (0)
size = ~size; // Negate all bits, thus all bits are set to one (1)

Jak dotąd mamy wynik -1 do momentu, gdy rozmiar jest intem ze znakiem.

size = (unsigned int)size >> 1; // Shift the bits of size one position to the right.

Jak mówi Standard, bity, które są przesunięte, wynoszą 1, jeśli zmienna jest podpisana i ujemna, oraz 0, jeśli zmienna byłaby bez znaku lub ze znakiem i dodatnią.

Ponieważ rozmiar jest oznaczony i ujemny, przesunęlibyśmy bit znaku, który wynosi 1, co niewiele pomaga, więc rzutujemy na wartość int bez znaku, zmuszając zamiast tego do przesunięcia w 0, ustawiając bit znaku na 0, pozostawiając wszystkie pozostałe bity na 1.

cout << size << endl; // Prints out size which is now set to maximum positive value.

Mogliśmy również użyć maski i xor, ale wtedy musieliśmy znać dokładny rozmiar bitu zmiennej. Dzięki przesunięciu z przodu bitów nie musimy w żadnym momencie wiedzieć, ile bitów int ma na komputerze lub kompilatorze, ani też nie potrzebujemy dołączać dodatkowych bibliotek.

MJeB
źródło
1
cout << "INT_MAX:\t" << (int) ((~((unsigned int) 0)) >> 1) << '\n' << "UINT_MAX:\t" << ~((unsigned int) 0) << endl;
Slaiyer
15
#include <climits>
#include <iostream>
using namespace std;

int main() {
  cout << INT_MAX << endl;
}

źródło
1
Nie nazwałbym INT_MAX „rozwiązaniem dla C”. Jest jednak stara i przestarzała w C ++.
Paul Tomblin,
6
Myślę, że obie odpowiedzi są w C ++. numeric_limits<int>::max()- działa również w kontekstach szablonowych, ale (z jakiegoś niezrozumiałego powodu dla mnie) nie może być używany jako stała czasu kompilacji. INT_MAX- to makro, całkiem bezużyteczne w funkcjach szablonu, ale może być używane jako stała czasu kompilacji.
UncleBens
17
Zabawne jest to, że implementacja numeric_limits <int> :: max w msvc wygląda następująco: return (INT_MAX);
Nikola Smiljanić
13
@paul Odniesienie do wycofania, proszę. I zgadnij, jak numeric_limits implementuje max ()? Zgadza się, „return INT_MAX”, przynajmniej w GCC 4.4.0.
2
@UncleBens: funkcje wbudowane obecnie nie mogą być zredukowane do stałych wyrażeń.
Georg Fritzsche
1

Oto makro, którego używam, aby uzyskać maksymalną wartość dla liczb całkowitych ze znakiem, która jest niezależna od rozmiaru użytego typu liczby całkowitej ze znakiem i dla którego gcc -Woverflow nie będzie narzekać

#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);
long long e = SIGNED_MAX(e);
Philippe De Muyter
źródło
1

Dlaczego nie napisać fragmentu kodu takiego jak:

int  max_neg = ~(1 << 31);
int  all_ones = -1;
int max_pos = all_ones & max_neg;
Prabhu
źródło
28
Nie ma gwarancji, że int ma rozmiar 32 bity i nie ma gwarancji, że w pamięci będzie ujemny format liczby całkowitej. Co mniej ważne, nie ma potrzeby, aby ludzie patrzyli w górę „~”.
Sqeaky
0

OK, nie mam przedstawiciela do komentowania poprzedniej odpowiedzi (Philippe'a De Muytera) ani podnoszenia jej wyniku, stąd nowy przykład wykorzystujący jego definicję dla SIGNED_MAX trywialnie rozszerzoną dla typów bez znaku:

// 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(unsigned int) // on ARM: 4294967295
// then we can have:
unsigned int width = UINT_MAX;

W przeciwieństwie do tego lub innego nagłówka, tutaj używamy prawdziwego typu z kompilatora.

A. Genchev
źródło
0
#include <iostrema>

int main(){
    int32_t maxSigned = -1U >> 1;
    cout << maxSigned << '\n';
    return 0;
}

Może to zależeć od architektury, ale działa przynajmniej w mojej konfiguracji.

macmur
źródło
-1

Dla określonej maksymalnej wartości int zwykle piszę w notacji szesnastkowej:

int my_max_int = 0x7fffffff;

zamiast nieregularnej wartości dziesiętnej:

int my_max_int = 2147483647;
Hao
źródło
-1

A co z (1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2)). To jest to samo co 2^(8*sizeof(int)-2) - 1 + 2^(8*sizeof(int)-2).

Jeśli 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].

Nie możesz użyć, 2*(1 << (8*sizeof(int)-2)) - 1ponieważ będzie przepełniony, ale (1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))działa.

izanbf1803
źródło