11

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

# define INT_MIN (-INT_MAX - 1)

# define INT_MAX 2147483647

此外,这个头文件中的所有 XXX_MAX 似乎都是从一个数字常量显式定义的。

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

我尝试了以下方法:

~((int)-1)

但这似乎不正确。

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

4

5 回答 5

10

对于INT_MAX标准 header中的 ,实现者的双手被要求在预处理器指令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可能会导致引发实现定义的信号,而不是获得实现定义的值,但是当您处理将被评估为的常量表达式时,这不会发生编译时。

于 2013-07-23T05:16:59.287 回答
2

我喜欢这些定义:

#define INT_MIN (1 << (sizeof(int)*CHAR_BIT-1))
#define INT_MAX (-(INT_MIN+1))
于 2016-02-24T17:25:07.803 回答
2

不,因为没有可移植的方法来知道int和之间的值位数的差异unsigned

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

(int)(UINT_MAX >> (value_bits<unsigned> - value_bits<int>))

可惜没有办法得到value_bits<unsigned> - value_bits<int>

在 C++ 中,这似乎可以通过模板元编程实现,从 15 位开始递归。(范围 [-32767, 32767] 保证可以用 表示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__;(

编辑:哎呀!

max.cpp: In instantiation of 'const int max0<32>::value':
max.cpp:17:51:   recursively required from 'const int max1<16>::value'
max.cpp:17:51:   required from 'const int max1<15>::value'
max.cpp:28:28:   required from here
max.cpp:4:52: warning: integer overflow in expression [-Woverflow]
     static const int value = max0<bits - 1>::value * 2 + 1;
                              ~~~~~~~~~~~~~~~~~~~~~~^~~
max.cpp:4:22: error: overflow in constant expression [-fpermissive]
     static const int value = max0<bits - 1>::value * 2 + 1;
                      ^~~~~
max.cpp:4:22: error: overflow in constant expression [-fpermissive]
max.cpp:4:22: error: overflow in constant expression [-fpermissive]
max.cpp: In instantiation of 'const int max0<914>::value':
max.cpp:17:51:   recursively required from 'const int max1<16>::value'
max.cpp:17:51:   required from 'const int max1<15>::value'
max.cpp:28:28:   required from here
max.cpp:4:52: fatal error: template instantiation depth exceeds maximum of 900 (use -ftemplate-depth= to increase the maximum)
     static const int value = max0<bits - 1>::value * 2 + 1;
                              ~~~~~~~~~~~~~~~~~~~~~~^~~
compilation terminated.
于 2017-11-03T08:40:28.463 回答
0

嗯,可以试试

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

哪个“应该”跨平台工作,字长不同,甚至有符号整数值的不同表示。(unsigned) -1将可移植地产生该UINT_MAX值,即全位模式。将其除以 2 应成为相应有符号整数类型的预期最大值,该值用于表示符号的位。

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

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

于 2013-07-23T03:14:22.213 回答
0

如果我们假设 1 或 2 的补码表示法和 8 位/字节且没有填充:

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

我没有看到班次或加班有任何溢出。我也没有看到UB。我想一个可以使用CHAR_BIT而不是 8。

在 1 和 2 的恭维中,最大 int 将是power(2,(sizeof(int)*Bits_per_byte - 1) - 1. 我们将使用转变而不是权力,但我们不能一次转变太多。所以我们power(2,(sizeof(int)*Bits_per_byte - 1)通过两次做一半来形成。但是溢出是一个禁忌,所以在添加第二半之前减去 1 而不是在末尾。我用了很多()来强调评估顺序。

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

计算 INT_MIN 在 2和1 的恭维中工作有点棘手,但类似的方法也可以,但这是另一个问题。

于 2013-07-23T03:54:06.873 回答