整数(或数字,就此而言)是不同的(逐字节)还是相同的(总共)表示?
C 允许多种编码方式 - 有些编码比其他编码更常见。然而,所有这些都受到一些规则的约束。
以层级为例,使用signed int。
在二进制中,这将是 111...111000000001,其中第一个 1 是符号位。
第 1 层:(位宽 N,值位 M)一个 "signed 整数占用 N 位。对于 signed 整数,只有一个符号位和M 值位和0个或更多(稀有)填充位。总计N。这3组和位的顺序没有定义。相反,>>、+ 等操作是用抽象定义的数值规范。例如左移值加倍。M的值很大程度上决定了int的范围。
// common implementations.
int: N=32, M=31
int: N=16, M=15
第 2 层:(2 的补码、符号/大小或 1 的补码)从具有值为 1 的最低有效位开始顺序排列值位并且下一位的值为2,然后是 4,然后是 8,等等。压倒性的常见 2 的补码布局中的 符号 位的值为 -2M。其他布局主要用于历史用途。
// Common implementations include:
int: N=32, M=31, 2's complement
int: N=16, M=15, 2's complement
第 3 层:字节宽度
int 占用 N 位,但位/字节(最小可寻址单元)的数量通常为 8 位/字节,但也存在其他的,例如 16、64 和历史上的 9、18 等. 必须至少为 8。目前,考虑近乎普遍的选择是 8 位/字节。
// Common implementations include:
int: N=32, M=31, 2's complement, 4 bytes
int: N=16, M=15, 2's complement, 2 bytes
第 4 层:字节序。
对于多个字节的典型int 代码,int 上的最低可寻址字节是编码最低有效位还是最高有效位或其他?最常见的 2 个是 little endian 和 big endian,如 OP 所示。还存在其他稀有字节序。
// Common implementations include:
int: N=32, M=31, 2's complement, 4 bytes, big endian
int: N=32, M=31, 2's complement, 4 bytes, little endian
int: N=16, M=15, 2's complement, 2 bytes, little endian
例子
值为-512,第一个字节的值是多少?
二进制:111...1110_00000001,第一位为符号位。
-511--> 0xFF (int: N=32, M=31, 2's complement, 4 bytes, big endian)
-511--> 0x01 (int: N=32, M=31, 2's complement, 4 bytes, little endian)
-511--> 0x01 (int: N=16, M=15, 2's complement, 2 bytes, little endian)
-511--> 0xFE (int: N=16, M=15, 2's complement, 2 bytes, big endian)