Perhatikan bahwa titik-mengambang minadalah nilai positif minimum , sedangkan bilangan bulat minadalah nilai minimum. Hal yang sama berlaku untuk makro C / konstanta.
dalle
4
di C99 Anda juga bisa menggunakan UINT64_MAX dan INT64_MAX
Dmitry Vyal
3
@DmitryVyal: Ya Anda bisa, tetapi itu adalah batas uint64_tdan int64_t, bukan dari int.
Keith Thompson
Di C ++, saya menggunakan kode yang sama seperti ditunjukkan di atas: #include <limits>dan int imax = std::numeric_limits<int>::max();, tapi saya mendapatkan kesalahan Can't resolve struct member 'max'. Adakah ide mengapa ini terjadi, dan bagaimana cara memperbaikinya? Saya menggunakan CLion IDE, dengan CMake dan C ++ 11 di Ubuntu 14.04. Saya pikir ini terkait dengan masalah ini
modulitos
1
Semoga ini membantu seseorang, karena itu adalah bug CLion IDE yang saya perbaiki dengan menggunakan CLion terbaru (build 138.2344 - CLion sedang dalam fase Early Access Program, dan karenanya tidak stabil)
modulitos
30
Saya tahu ini pertanyaan lama tapi mungkin seseorang dapat menggunakan solusi ini:
int size =0;// Fill all bits with zero (0)
size =~size;// Negate all bits, thus all bits are set to one (1)
Sejauh ini kita memiliki -1 sebagai hasilnya sampai ukuran adalah int yang ditandatangani.
size =(unsignedint)size >>1;// Shift the bits of size one position to the right.
Seperti yang dikatakan Standard, bit yang digeser adalah 1 jika variabel ditandatangani dan negatif dan 0 jika variabel tidak ditandatangani atau ditandatangani dan positif.
Karena ukuran masuk dan negatif, kami akan menggeser bit masuk yang 1, yang tidak banyak membantu, jadi kami menggunakan int unsigned, memaksa untuk menggeser dalam 0 sebagai gantinya, mengatur bit tanda ke 0 sambil membiarkan semua bit lainnya tetap 1.
cout << size << endl;// Prints out size which is now set to maximum positive value.
Kita juga bisa menggunakan mask dan xor tetapi kemudian kita harus tahu bitsize variabel yang tepat. Dengan menggeser bit di depan, kita tidak perlu tahu kapan saja berapa banyak bit yang dimiliki int pada mesin atau kompiler atau kita tidak perlu menyertakan perpustakaan tambahan.
Saya tidak akan menyebut INT_MAX "solusi untuk C". Itu sekolah tua dan usang di C ++, meskipun.
Paul Tomblin
6
Saya pikir keduanya adalah jawaban C ++. numeric_limits<int>::max()- berfungsi juga dalam konteks templat, tetapi (untuk beberapa alasan yang tak terduga bagi saya) tidak dapat digunakan sebagai konstanta waktu kompilasi. INT_MAX- Adalah makro, cukup berguna dalam fungsi template, tetapi dapat digunakan sebagai konstanta waktu kompilasi.
UncleBens
17
Lucunya numeric_limits <int> :: implementasi max di msvc terlihat seperti ini: return (INT_MAX);
Nikola Smiljanić
13
@paul Referensi untuk penghinaan silakan. Dan tebak bagaimana numeric_limits mengimplementasikan max ()? Itu benar, "return INT_MAX", setidaknya pada GCC 4.4.0.
2
@UncleBens: fungsi sebaris saat ini tidak dapat direduksi menjadi ekspresi konstan.
Georg Fritzsche
1
Berikut ini adalah makro yang saya gunakan untuk mendapatkan nilai maksimum untuk bilangan bulat yang ditandatangani, yang tidak tergantung pada ukuran jenis bilangan bulat yang ditandatangani yang digunakan, dan yang gcc -Woverflow tidak akan mengeluh
#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);
Tidak ada jaminan bahwa int berukuran 32 bit dan tidak ada jaminan tentang format integer negatif dalam memori. Yang kurang penting, tidak perlu membuat orang mencari '~'.
Sqeaky
0
OK Saya tidak punya tanggapan untuk mengomentari jawaban sebelumnya (dari Philippe De Muyter) atau menaikkan skornya, maka contoh baru menggunakan definisinya untuk SIGNED_MAX yang secara sepele diperluas untuk jenis yang tidak ditandatangani:
// 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;
Tidak seperti menggunakan header ini atau itu, di sini kita menggunakan tipe asli dari kompiler.
Bagaimana dengan (1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2)). Ini sama dengan 2^(8*sizeof(int)-2) - 1 + 2^(8*sizeof(int)-2).
Jika 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].
Anda tidak dapat menggunakan 2*(1 << (8*sizeof(int)-2)) - 1karena itu akan meluap, tetapi (1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))berfungsi.
int
denganlong long int
jawaban Gregories ...-pedantic
) mendukungnya.Jawaban:
Dalam C ++:
lalu gunakan
std::numeric_limits
adalah tipe templat yang dapat dipakai dengan jenis lain:Dalam C:
lalu gunakan
atau
sumber
min
adalah nilai positif minimum , sedangkan bilangan bulatmin
adalah nilai minimum. Hal yang sama berlaku untuk makro C / konstanta.uint64_t
danint64_t
, bukan dariint
.#include <limits>
danint imax = std::numeric_limits<int>::max();
, tapi saya mendapatkan kesalahanCan't resolve struct member 'max'
. Adakah ide mengapa ini terjadi, dan bagaimana cara memperbaikinya? Saya menggunakan CLion IDE, dengan CMake dan C ++ 11 di Ubuntu 14.04. Saya pikir ini terkait dengan masalah iniSaya tahu ini pertanyaan lama tapi mungkin seseorang dapat menggunakan solusi ini:
Sejauh ini kita memiliki -1 sebagai hasilnya sampai ukuran adalah int yang ditandatangani.
Seperti yang dikatakan Standard, bit yang digeser adalah 1 jika variabel ditandatangani dan negatif dan 0 jika variabel tidak ditandatangani atau ditandatangani dan positif.
Karena ukuran masuk dan negatif, kami akan menggeser bit masuk yang 1, yang tidak banyak membantu, jadi kami menggunakan int unsigned, memaksa untuk menggeser dalam 0 sebagai gantinya, mengatur bit tanda ke 0 sambil membiarkan semua bit lainnya tetap 1.
Kita juga bisa menggunakan mask dan xor tetapi kemudian kita harus tahu bitsize variabel yang tepat. Dengan menggeser bit di depan, kita tidak perlu tahu kapan saja berapa banyak bit yang dimiliki int pada mesin atau kompiler atau kita tidak perlu menyertakan perpustakaan tambahan.
sumber
cout << "INT_MAX:\t" << (int) ((~((unsigned int) 0)) >> 1) << '\n' << "UINT_MAX:\t" << ~((unsigned int) 0) << endl;
sumber
numeric_limits<int>::max()
- berfungsi juga dalam konteks templat, tetapi (untuk beberapa alasan yang tak terduga bagi saya) tidak dapat digunakan sebagai konstanta waktu kompilasi.INT_MAX
- Adalah makro, cukup berguna dalam fungsi template, tetapi dapat digunakan sebagai konstanta waktu kompilasi.Berikut ini adalah makro yang saya gunakan untuk mendapatkan nilai maksimum untuk bilangan bulat yang ditandatangani, yang tidak tergantung pada ukuran jenis bilangan bulat yang ditandatangani yang digunakan, dan yang gcc -Woverflow tidak akan mengeluh
sumber
Mengapa tidak menulis kode seperti:
sumber
OK Saya tidak punya tanggapan untuk mengomentari jawaban sebelumnya (dari Philippe De Muyter) atau menaikkan skornya, maka contoh baru menggunakan definisinya untuk SIGNED_MAX yang secara sepele diperluas untuk jenis yang tidak ditandatangani:
Tidak seperti menggunakan header ini atau itu, di sini kita menggunakan tipe asli dari kompiler.
sumber
Mungkin bergantung pada arsitektur tetapi berfungsi setidaknya di setup saya.
sumber
Untuk nilai maksimum spesifik int , saya biasanya menulis notasi heksadesimal:
alih-alih nilai desimal tidak teratur:
sumber
Bagaimana dengan
(1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))
. Ini sama dengan2^(8*sizeof(int)-2) - 1 + 2^(8*sizeof(int)-2)
.Jika
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]
.Anda tidak dapat menggunakan
2*(1 << (8*sizeof(int)-2)) - 1
karena itu akan meluap, tetapi(1 << (8*sizeof(int)-2)) - 1 + (1 << (8*sizeof(int)-2))
berfungsi.sumber