我目前正在按照“C primer plus”一书学习C编程语言。
在溢出部分,作者指出
minimum range for long is
–2,147,483,647 to 2,147,483,647
, corresponding to a 32-bit unit.
我想知道,32 位单元的最大值不应该是 2,147,483,648
而不是作者所说的 2,147,483,647
吗?
我也看到了on tutorial point 32 位单元的范围是 –2,147,483,648 到 2,147,483,647
。我非常困惑。
另外,当我运行代码时
int i = 2147483647;
printf("%d %d %d\n", i, i+1, i+2);
得到结果2147483647 -2147483648 -2147483647
,支持32位单元的取值范围是–2,147,483,648 to 2,147,483,647
。那么哪个是正确的呢?
PS - 我以前研究过二进制补码系统,据我所知,最大数应该始终是 -(min number) + 1
,所以从二进制补码系统,我认为 –2,147,483,647 到 2,147,483,648
更可能是正确的。但是上面的printf
好像支持–2,147,483,648 to 2,147,483,647
,和作者说的–2,147,483,647 to 2,147,483,647
不一样。
最佳答案
32 位内存可以编码,最多,232 个不同的值。
C 整数由 3 部分组成:符号位、值位和很少填充位。对于这个答案,假设填充位数为零。
C 支持 3 种整数编码:2 的补码、1 的补码、符号大小。
一个 32 位整数的范围是
- 2 的补码:
[–2,147,483,648 ... 2,147,483,647]
目前最常见 - 1 的补码:
[–2,147,483,647 ... 2,147,483,647]
1 个范围小于 2 个 - 符号大小:
[–2,147,483,647 ... 2,147,483,647]
1 个范围小于 2 个
然后所有 3 个都满足 long
的 C 要求:
Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.
- minimum value for an object of typelong int
LONG_MIN
-2147483647
- maximum value for an object of typelong int
LONG_MAX
+2147483647
C11dr §5.2.4.2.1 1
请注意 long
以及int
可以是 64 位的,范围更广。
I was wondering, shouldn't the max value for a 32 bit unit be 2,147,483,648
2,147,483,648 与 32 位不兼容 2's complement因为这需要 33 位。
避免 C 中的整数溢出,因为它是未定义的行为 (UB)。 OP 的文本输出不是确定的。
int i = 2147483647; // v----v----- UB
printf("%d %d %d\n", i, i+1, i+2);
而是根据 <limits.h>
打印最小值/最大值:
printf("int min:%d max:%d\n", INT_MIN, INT_MAX);
printf("long min:%ld max:%ld\n", LONG_MIN, LONG_MAX);
即使 OP 的最小整数是 –2,147,483,648,这并不意味着它是所有实现的最小值。 C 规范只需要 –2,147,483,647 或更少。
关于c - 32位单元C编程语言的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46760900/