整数表示
在本节 ,我们描述用位来编码整数的两种不同的方式 :一种只能表示非负数,而另一种能够表示负数、零和正数。后面我们将会看到它们在数学属性和机器级实现方面密切相关。我们还会研究扩展或者收缩一个已编码整数以适应不同长度表示的效果。
下面列出了我们引 的数学术语,用于精确定义和描述计算机如何编码和操作整数。这些术语将在描述的过程中介绍,在此处列出作为参考。
- 常数
- 最小补码值:
- 最大补码值:
- 最大无符号数:
- 函数
- 二进制转补码:
- 二进制转无符号数:
- 无符号数转二进制:
- 无符号转补码:
- 补码转二进制:
- 补码转无符号数:z
- 操作
- 补码加法:
- 无符号数加法:
- 补码乘法:
- 无符号数乘法:
- 补码取反:
- 无符号数取反:
2. 2. 1 整型数据类型
C 语言支持多种整型数据类型——表示有限范围的整数。这些类型如图 2-9、2-10 所示,其中还给出了“典型" 32 位和 64 位机器的取值范围。每种类型都能用关键字来指定大小,这些关键字包括 char、short、long,同时还可以指示被表示的数字是非负数(声明为 unsigned),或者可能是负数(默认)。如图 2-3 所示,为这些不同的大小分配的字节数根据程序编译为 32 位还是 64 位而有所不同。根据字节分配,不同的大小所能表示的值的范围是不同的。这里给出来的唯一一个与机器相关的取值范围是大小指示符 long 的。大多数 64 位机器使用 8 个字节的表示,比 32 位机器上使用的 4 个字节的表示的取值范围大很多。
图 2-9 32 位程序上 C 语言整型数据类型的典型取值范围
C 数据类型 | 最小值 | 最大值 |
---|---|---|
[signed] char | -128 | 127 |
unsigned char | 0 | 255 |
short | -32768 | 32767 |
unsigned short | 0 | 65535 |
int | -2 147 483 648 | 2 147 483 647 |
unsigned | 0 | 4 294 967 295 |
int32_t | -2 147 483 648 | 2 147 483 647 |
uint32_t | 0 | 4 294 967 295 |
int64 | -9 223 372 036 854 775 808 | 9 223 372 036 854 775 807 |
uint64_t | 0 | 18 446 744 073 709 551 615 |
图 2-10 64 位程序上 C 语言整型数据类型的典型取值范围
C 数据类型 | 最小值 | 最大值 |
---|---|---|
[signed] char | -128 | 127 |
unsigned char | 0 | 255 |
short | -32768 | 32767 |
unsigned short | 0 | 65535 |
int | -2 147 483 648 | 2 147 483 647 |
unsigned | 0 | 4 294 967 295 |
long | -9 223 372 036 854 775 808 | 9 223 372 036 854 775 807 |
unsigned long | 0 | 18 446 744 073 709 551 615 |
int32_t | -2 147 483 648 | 2 147 483 647 |
uint32_t | 0 | 4 294 967 295 |
int64 | -9 223 372 036 854 775 808 | 9 223 372 036 854 775 807 |
uint64_t | 0 | 18 446 744 073 709 551 615 |
图 2-9 和图 2-10 中一个很值得注意的特点是取值范围不是对称的 —— 负数的范围比整数的范围大 1。当我们考虑如何表示负数的时候,会看到为什么会这样。
C 语言标准定义了每种数据类型必须能够表示的最小的取值范围。如图 2-11 所示,它们的取值范围与图 2-9 和图 2-10 所示的典型实现一样或者小一些。特别地,除了固定大小的数据类型是例外,我们看到它们只要求正数和负数的取值范围是对称的。此外,数据类型 int 可以用 2 个字节的数字来实现,而这几乎回退到了 16 位机器的时代。还可以看到,long 的大小可以用 4 个字节的数字来实现,对 32 位程序来说这是很典型的。固定大小的数据类型保证数值的范围与图 2-9 给出的典型数值一致,包括负数与正数的不对称性。
图 2-11 C 语言整型数据类型的保证的取值范围。C 语言标准要求这些数据类型必须至少具有这样的取值范围
C 数据类型 | 最小值 | 最大值 |
---|---|---|
[signed] char | -127 | 127 |
unsigned char | 0 | 255 |
short | -32767 | 32767 |
unsigned short | 0 | 65535 |
int | -32767 | 32767 |
unsigned | 0 | 65535 |
long | -2 147 483 647 | 2 147 483 647 |
unsigned long | 0 | 4 294 967 295 |
int64 | -9 223 372 036 854 775 808 | 9 223 372 036 854 775 807 |
uint64_t | 0 | 18 446 744 073 709 551 615 |
C、C++ 都支持有符号(默认)和无符号数。Java 只支持有符号数。