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 =(unsignedint)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.
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);longlong e = SIGNED_MAX(e);
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(unsignedint)// on ARM: 4294967295// then we can have:unsignedint width = UINT_MAX;
W przeciwieństwie do tego lub innego nagłówka, tutaj używamy prawdziwego typu z kompilatora.
int
zelong long int
w Gregories odpowiedź ...-pedantic
) go obsługują.Odpowiedzi:
W C ++:
następnie użyj
std::numeric_limits
jest typem szablonu, którego instancję można utworzyć z innymi typami:W C:
następnie użyj
lub
źródło
min
są minimalną wartością dodatnią , gdzie jako liczby całkowitemin
są wartością minimalną. To samo dotyczy makr / stałych języka C.uint64_t
iint64_t
nieint
.#include <limits>
iint imax = std::numeric_limits<int>::max();
, ale pojawia się błądCan'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ąWiem, że to stare pytanie, ale może ktoś może skorzystać z takiego rozwiązania:
Jak dotąd mamy wynik -1 do momentu, gdy rozmiar jest intem ze znakiem.
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.
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.
źródło
cout << "INT_MAX:\t" << (int) ((~((unsigned int) 0)) >> 1) << '\n' << "UINT_MAX:\t" << ~((unsigned int) 0) << endl;
źródło
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.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ć
źródło
Dlaczego nie napisać fragmentu kodu takiego jak:
źródło
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:
W przeciwieństwie do tego lub innego nagłówka, tutaj używamy prawdziwego typu z kompilatora.
źródło
Może to zależeć od architektury, ale działa przynajmniej w mojej konfiguracji.
źródło
Dla określonej maksymalnej wartości int zwykle piszę w notacji szesnastkowej:
zamiast nieregularnej wartości dziesiętnej:
źródło
A co z
(1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))
. To jest to samo co2^(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)) - 1
ponieważ będzie przepełniony, ale(1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))
działa.źródło