Czy istnieje kod do znalezienia maksymalnej wartości liczby całkowitej (zgodnie z kompilatorem) w C / C ++, jak Integer.MaxValue
funkcja w java?
int
ze long long int
w Gregories odpowiedź ...
-pedantic
) go obsługują.
Czy istnieje kod do znalezienia maksymalnej wartości liczby całkowitej (zgodnie z kompilatorem) w C / C ++, jak Integer.MaxValue
funkcja w java?
int
ze long long int
w Gregories odpowiedź ...
-pedantic
) go obsługują.
Odpowiedzi:
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;
min
są minimalną wartością dodatnią , gdzie jako liczby całkowite min
są wartością minimalną. To samo dotyczy makr / stałych języka C.
uint64_t
i int64_t
nie int
.
#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ą
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.
cout << "INT_MAX:\t" << (int) ((~((unsigned int) 0)) >> 1) << '\n' << "UINT_MAX:\t" << ~((unsigned int) 0) << endl;
#include <climits>
#include <iostream>
using namespace std;
int main() {
cout << INT_MAX << endl;
}
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ć
#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);
Dlaczego nie napisać fragmentu kodu takiego jak:
int max_neg = ~(1 << 31);
int all_ones = -1;
int max_pos = all_ones & max_neg;
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 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)) - 1
ponieważ będzie przepełniony, ale (1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))
działa.