这是一种在不使用limits
库的情况下确定整数最大值的安全方法吗?
int max_int = (unsigned int) -1 >> 1;
答案 0 :(得分:0)
我相信你提出的代码:
int max_int = (unsigned int) -1 >> 1;
不是确定有符号整数类型的最大值的安全方法(根据标准),但它绝对适用于大多数体系结构。我会尽力小心地激励下面的陈述。
首先要注意的是:
6.2.5类型
...
对于每个有符号整数类型,都有一个对应的(但是 另外)无符号整数类型(用关键字指定) unsigned)使用相同数量的存储空间(包括符号) 信息)并具有相同的对齐要求。 ...
有符号整数类型的非负值范围是相应无符号整数类型的子范围,并且 每种类型中相同值的表示是相同的。一个 涉及无符号操作数的计算永远不会溢出,因为a 结果无法由结果无符号整数表示 type是以大于最大值的数量减少的模数 可以由结果类型表示的值。
标准的这些行确保(unsigned int) -1
转换为UINT_MAX
。然后是以下内容:
6.5.7按位移位运算符
...
- E1的结果> E2是E1右移E2位位置。如果E1具有无符号类型,或者E1具有有符号类型和非负数 值,结果的值是商的整数部分 E1 / 2 ^ E2。
确保数字的值除以2.现在它出现了棘手的点。根据以下内容:
6.2.6.2整数类型
- 对于unsigned char以外的无符号整数类型,对象表示的位应分为两组:值位 和填充位(不需要后者中的任何一个)。如果有N. 值位,每个位应表示1之间的不同2的幂 和2N-1,以便该类型的物体能够 使用纯二进制表示0到2N - 1之间的值 表示;这应该被称为价值表示。该 任何填充位的值都未指定。
- 对于有符号整数类型,对象表示的位应分为三组:值位,填充位和 标志位。不需要任何填充位;确切地说 一个标志位。作为值位的每个位应具有相同的值 作为相应对象表示中的相同位 无符号类型(如果有符号类型中有M个值位且N in 无符号类型,则M <= N)。
有符号整数类型由:
组成而无符号整数类型由以下组成:
由于相应类型的有符号和无符号整数必须具有相同的存储,我认为M+X+1 == N+Y
。
您的假设是,当仅移位一位时M = N - 1
或另外说明,int
中的填充位数与{{1}中的填充位数相同}} 的
现在,根据转换规则:
6.3.1.3有符号和无符号整数
- 当整数类型的值转换为_Bool以外的另一个整数类型时,如果该值可以用新类型表示,则 没有变化。
- 否则,如果新类型是无符号的,则通过重复添加或减去一个超过最大值的值来转换该值 可以用新类型表示,直到值在范围内 新型。
- 否则,新类型已签名且值无法在其中表示;结果是实现定义的还是 提出了实现定义的信号。
如果您对正在使用的体系结构的假设是正确的,那么您将点击第一个项目符号,否则您将达到第三个项目,行为将是实现已定义。
后一个选项不会“安全”,因为您无法仅根据C标准确保程序的独特行为,并且您不能依赖于有一些功能,你可能需要正确处理这种情况。