2.3 定点数的表示
无符号数与带符号数,原码、反码、补码、移码的定义与表示范围,C 语言中的整数类型转换、符号扩展,以及大端小端与边界对齐。
无符号数与带符号数
- 无符号数:整个机器字长的全部二进制位均为数值位,没有符号位。 位无符号数的表示范围为 。
- 带符号数:最高位用作符号位,“0”表示正,“1”表示负。根据数值位编码方式的不同,有原码、反码、补码和移码。
- 计算机中的定点数分为定点整数(小数点隐含在最低位之后,纯整数)和定点小数(小数点隐含在符号位之后,纯小数)。
四种机器数
交互演示定点整数的原码、反码、补码与移码
② 点击下面的位,观察同一个机器码在不同解释下的真值:
无符号数182原码−54反码−73补码−74移码54
补码的"模"为 2ⁿ:[x]补 = 2ⁿ + x(mod 2ⁿ)。快速求 −|x| 的补码:写出 |x| 的 n 位二进制(符号位为 0),从右往左找到第一个 1,这个 1 及其右边的 0 不变,左边各位(含符号位)全部取反。
| 编码 | 正数 | 负数 | 位整数的范围 | 0 的表示 |
|---|---|---|---|---|
| 原码 | 符号位 0 + 数值的绝对值 | 符号位 1 + 数值的绝对值 | +0、−0 两种 | |
| 反码 | 同原码 | 原码数值位取反 | +0、−0 两种 | |
| 补码 | 同原码 | 反码 + 1 | 唯一 | |
| 移码 | 真值 + | 真值 + | 唯一 |
C 语言中的整数
C 语言中 char、short、int、long 默认为带符号整数(补码表示),加 unsigned 修饰为无符号整数。
有符号数与无符号数的转换
C 语言允许在不同的数据类型之间做强制类型转换。在 int 与 unsigned int 之间转换时,位模式保持不变,只是解释方式改变:
short x = -4321;
unsigned short y = (unsigned short)x; // x 的补码为 EF1FH,y = 61215
不同字长整数之间的转换
- 长 → 短(截断):直接丢弃高位,保留低位。例如
int型的 165537(0002 86A1H)转为short后为 86A1H = −31071。 - 短 → 长(扩展):
- 无符号数:零扩展,高位补 0;
- 有符号数:符号扩展,高位补符号位。例如
short型 −4321(EF1FH)扩展为int为 FFFF EF1FH,数值不变。
数据的存储与排列
大端与小端
现代计算机通常按字节编址,一个多字节数据(如 4 字节 int)占用多个连续的存储单元,其地址为最小的那个字节的地址。多字节数据在存储器中的排列方式有两种:
- 大端方式:先存储高位字节,后存储低位字节,字中的字节顺序与原序列相同(便于阅读);
- 小端方式:先存储低位字节,后存储高位字节,字中的字节顺序与原序列相反(Intel x86 采用)。
在检查底层机器级代码时,需要分清大端/小端。例如 mov 0x12345678, %eax 在小端机器上的机器码中,立即数部分为 78 56 34 12。
边界对齐
假设存储字长为 32 位,可按字节、半字、字寻址。边界对齐要求:字地址为 4 的整数倍,半字地址为 2 的整数倍,以便一次访存就能取出一个完整的数据。这样做以空间换时间,减少访存次数。
C 语言中的 struct 也存在对齐问题:每个成员按其类型的大小对齐,结构体的总大小为最大成员大小的整数倍。
struct { char a; int b; short c; } s1; // 1 + 3(填充) + 4 + 2 + 2(填充) = 12 字节
struct { int b; short c; char a; } s2; // 4 + 2 + 1 + 1(填充) = 8 字节
即时练习
即时练习5 题
点击选项即可作答
- 1假定有 4 个整数用 8 位补码分别表示为 r1 = FEH,r2 = F2H,r3 = 90H,r4 = F8H。若将运算结果存放在一个 8 位寄存器中,则下列运算会发生溢出的是( )。
- 2有如下 C 语言程序段:
short si = -32767; unsigned short usi = si;
执行上述两条语句后,usi 的值为( )。 - 3某计算机字长为 32 位,按字节编址,采用小端方式存放数据。假定有一个 double 型变量,其机器数表示为 1122 3344 5566 7788H,存放在 0000 8040H 开始的连续存储单元中,则存储单元 0000 8046H 中存放的是( )。
- 4若 x = 103,y = −25,则下列表达式采用 8 位定点补码运算实现时,会发生溢出的是( )。
- 58 位移码 1000 0000 表示的真值是( )。
学完了吗?
标记完成后,侧栏会显示进度。进度仅保存在本浏览器中。