有可行的方法来定义INT_MAX吗?

时间:2013-07-23 02:57:55

标签: c gcc int

我在/usr/include/limits.h中找到了以下定义:

# define INT_MIN (-INT_MAX - 1)

# define INT_MAX 2147483647

此外,似乎此头文件中的所有XXX_MAX都是从数字常量中明确定义的。

我想知道是否有一种可移植的方式(跨平台的不同字大小)来定义INT_MAX?

我尝试了以下内容:

~((int)-1)

但这似乎不正确。

一个简短的解释也受到高度重视。

5 个答案:

答案 0 :(得分:9)

对于标准头INT_MAX中的limits.h,实现者的手由于需要在预处理器#if指令中使用而受到限制。这排除了涉及sizeof或强制转换的任何内容。

如果您只想要一个适用于实际C表达式的版本,那么这可能会起作用:

(int)-1U/2 == (int)(-1U/2) ? (int)-1U : (int)(-1U/2)

这里的概念是int可能具有与unsigned相同数量的值位,或者少一个值位; C标准允许。为了测试它是什么,请检查转换结果(int)-1U。如果-1U适合int,则其值必须由强制转换保持不变,因此相等性为真。如果-1U不适合int,则转换会生成类型为int的实现定义结果。然而,无论价值是什么,仅仅通过可能值的范围,相等性将是错误的。

请注意,从技术上讲,转换为int可能会导致实现定义的信号被提升,而不是获得实现定义的值,但是当您处理时不会发生这种情况。一个常量表达式,将在编译时进行评估。

答案 1 :(得分:2)

我喜欢这些定义:

#define INT_MIN (1 << (sizeof(int)*CHAR_BIT-1))
#define INT_MAX (-(INT_MIN+1))

答案 2 :(得分:2)

不,因为没有可移植的方式来了解xsi:schemaLocationint之间的值位数差异。

有一种可移植的方法来获取unsigned,即UINT_MAX,因为无符号整数是模数类型。因此,-1u的表达式是

INT_MAX

很遗憾没有办法获得(int)(UINT_MAX >> (value_bits<unsigned> - value_bits<int>))

在C ++中,这似乎可以通过模板元编程实现,从15位开始递归。 (范围[-32767,32767]保证可在value_bits<unsigned> - value_bits<int>中表示。)

int

但我发现这是一种过度杀伤并坚持使用编译器定义的template<int bits> struct max0 { static const int value = max0<bits - 1>::value * 2 + 1; }; template<> struct max0<15> { static const int value = 32767; }; template<int bits> struct max1 { static const int value = max0<bits + 1>::value > max0<bits>::value ? max1<bits + 1>::value : max0<bits>::value; }; #define INT_MAX (max1<15>::value) ;(

编辑:哎呀!

__INT_MAX__

答案 3 :(得分:0)

好吧,可以试试

#define INT_MAX (int) ((unsigned) -1 / 2)

哪个“应该”在具有不同字大小的平台上工作,甚至可以使用有符号整数值的不同表示。 (unsigned) -1将可移植地生成UINT_MAX值,这是全比特一模式。将它除以2它应该成为相应的有符号整数类型的预期最大值,该值用于表示符号的位。

但为什么呢?其中的标准头文件和定义不应该是可移植的。

顺便说一句,您在上面引用的INT_MIN的定义是不可移植的。它特定于有符号整数的2的补码表示。

答案 4 :(得分:0)

如果我们假设1或2的赞美符号和8位/字节且没有填充:

#define INT_MAX  ((1 << (sizeof(int)*8 - 2)) - 1 + (1 << (sizeof(int)*8 - 2)))

我没有看到轮班中的任何溢出或添加。我也没有看到UB。我想可以使用CHAR_BIT而不是8。

在1和2的赞美中,max int将是power(2,(sizeof(int)*Bits_per_byte - 1) - 1。我们不会使用移位,而是使用移位,但我们不能同时移动太多。所以我们通过做两次两次来形成power(2,(sizeof(int)*Bits_per_byte - 1)。但是溢出是禁止的,所以在添加下半部分之前减去1而不是最后。我使用了很多()来强调评估顺序。

正如@caf所指出的,这个方法失败是否有填充位 - 不常见但可能。

计算INT_MIN对2的 1的恭维有点麻烦,但类似的方法也可行,但这是另一个问题。