我在/usr/include/limits.h中找到了以下定义:
# define INT_MIN (-INT_MAX - 1)
# define INT_MAX 2147483647
此外,似乎此头文件中的所有XXX_MAX都是从数字常量中明确定义的。
我想知道是否有一种可移植的方式(跨平台的不同字大小)来定义INT_MAX?
我尝试了以下内容:
~((int)-1)
但这似乎不正确。
一个简短的解释也受到高度重视。
答案 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:schemaLocation
和int
之间的值位数差异。
有一种可移植的方法来获取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的恭维有点麻烦,但类似的方法也可行,但这是另一个问题。