整数的最大值

220

在C/C++中是否有类似于Java的Integer.MaxValue函数用于查找整数的最大值(根据编译器)的代码?


1
有没有办法找到 long long int 的最大值? - d3vdpro
只需将格雷戈里的回答中的int替换为long long int即可... - Georg Fritzsche
1
除了 long long 不是 C++ 的一部分之外。 - anon
重复的例子,例如https://dev59.com/e3I-5IYBdhLWcg3wq6do - Georg Fritzsche
@Neil,没错,这是C99 - 但VC和GCC(没有-pedantic)支持它。 - Georg Fritzsche
不要将int和"integer"混淆。有几种整数类型;int只是其中之一。 - Keith Thompson
7个回答

387

在C++中:

#include <limits>

然后使用

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

std::numeric_limits是一个可以用其他类型进行实例化的模板类型:

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

在 C 语言中:

#include <limits.h>

然后使用

int imin = INT_MIN; // minimum value
int imax = INT_MAX;
或者
#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;

20
请注意,浮点数中的min是最小值,而整数中的min是最小值。C宏或常量也是如此。 - dalle
8
在C99中,您还可以使用UINT64_MAX和INT64_MAX。 - Dmitry Vyal
5
可以,但是这些限制适用于uint64_tint64_t,而不是int - Keith Thompson
1
希望这能帮到某些人,因为这是一个CLion IDE的错误,我通过使用最新的CLion(版本138.2344 - CLion处于早期访问计划阶段,因此不稳定)来修复了它。 - modulitos
2
一个花式的写法可以是这样的 (unsigned)-1/2 - Stavros Avramidis
显示剩余2条评论

36

我知道这是一个老问题,但也许有人可以使用这个解决方案:

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

到目前为止,当size是有符号整数时,我们的结果为-1。

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

根据标准,如果变量是有符号的且为负数,则移入的位为1;如果变量是无符号的或者有符号的且为正数,则移入的位为0。

由于size是有符号的且为负数,我们将会移入符号位(即1),这并没有什么帮助,所以我们将其强制转换为无符号整数,并强制移入0,将符号位置为0,同时保留所有其他位的值为1。

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

我们也可以使用掩码和异或运算,但是这样我们需要知道变量的确切位数。通过将位移放在前面,我们无需知道机器或编译器上int具有多少位,并且也不需要包含额外的库。


1
cout << "INT_MAX:\t" << (int) ((~((unsigned int) 0)) >> 1) << '\n' << "UINT_MAX:\t" << ~((unsigned int) 0) << endl; - Slaiyer

17
#include <climits>
#include <iostream>
using namespace std;

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

2
我不会称INT_MAX为“C的解决方案”。虽然它在C++中已经过时了,但它仍是老派的。 - Paul Tomblin
6
我认为这两个都是 C++ 的答案。numeric_limits<int>::max() - 可以在模板上下文中使用,但出于某种我无法理解的原因,不能用作编译时常量。INT_MAX - 是一个宏,在模板函数中没有什么用处,但可以用作编译时常量。 - UncleBens
19
有趣的是,MSVC上numeric_limits<int>::max的实现看起来像这样:return (INT_MAX); - Nikola Smiljanić
13
请提供“弃用”的参考资料。猜猜numeric_limits是如何实现max()的?没错,“return INT_MAX”,至少在GCC 4.4.0上是这样做的。 - anon
2
@UncleBens:目前无法将内联函数简化为常量表达式。 - Georg Fritzsche
显示剩余3条评论

2

何不编写如下代码:

int  max_neg = ~(1 << 31);
int  all_ones = -1;
int max_pos = all_ones & max_neg;

28
不能保证int类型的大小为32位,也不能保证内存中负整数的格式。其次,没有必要让人们去查找'~'符号的含义。 - Sqeaky

2

这是我用来获取有符号整数的最大值的宏,不受使用的有符号整数类型大小的影响,且 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);
long long e = SIGNED_MAX(e);

2

好的,我没有评论前一个答案(Philippe De Muyter的答案)的声望,也不能提高它的分数,因此我将使用他的define来为UNSIGNED_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(unsigned int) // on ARM: 4294967295
// then we can have:
unsigned int width = UINT_MAX;

与使用这个或那个头文件不同,这里我们使用编译器的真实类型。

1
#include <iostrema>

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

它可能与架构相关,但至少在我的设置中可以正常工作。

这可能是可行的,但重要的是要努力实现可移植性。 - Kingsley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接