数据表示

1264 字
6 分钟
数据表示

数据表示#

补码的表示范围#

假设机器字长为 n 位,补码可表示的数值范围:

2n1    n位补码    2n11-2^{\,n-1} \;\leq\; n\text{位补码} \;\leq\; 2^{\,n-1} - 1
字长范围举例
8 位128-128 ~ 127127int8_t
16 位32768-32768 ~ 3276732767int16_t
32 位231-2^{31} ~ 23112^{31}-1int
64 位263-2^{63} ~ 26312^{63}-1long long

不对称的原因:补码中负数比正数多一个(没有 −0),最小负数的绝对值比最大正数大 1。

移码#

为什么引入移码?#

浮点数的指数(阶码)可正可负。如果用补码表示指数,比较浮点数大小时会出问题。

比如两个正浮点数,指数分别是 +2-3

  • 补码:+2 = 00000010-3 = 11111101
  • 用无符号比较,11111101 反而 > 00000010,比较器会认为指数 -3+2 大 ✗

移码的思路:把整个指数范围往上”平移”一个固定值(偏置量),让所有存储的指数都变成非负数。这样用无符号整数比较就能正确判断浮点数大小,硬件比较器大大简化。

一句话:移码把有符号指数映射到无符号范围,让硬件用同一套比较电路就能比较浮点数。

计算公式#

移码 = 真值 + 偏置值

精度指数位数偏置值公式
单精度 (float)8 位127 (2⁷−1)移码 = 真值 + 127
双精度 (double)11 位1023 (2¹⁰−1)移码 = 真值 + 1023

通式:偏置值 = 2ⁿ⁻¹ − 1(n 为指数位数)

举例#

单精度下,真值指数 = -3

  • 移码 = -3 + 127 = 124
  • 二进制:01111100

真值指数 = +2

  • 移码 = 2 + 127 = 129
  • 二进制:10000001

现在无符号比较:129 > 124 ✓,正确反映了指数大小关系。

移码的本质#

移码的核心思想:把真值整体向上平移 2n12^{n-1},使所有值变成非负,从而能用无符号比较器做大小判断。

真值范围: -2^(n-1) ──────── 0 ──────── 2^(n-1)-1
│ │ │
▼ +2^(n-1) ▼ +2^(n-1) ▼ +2^(n-1)
移码范围: 0 ──────── 2^(n-1) ──────── 2^n-1
项目说明
偏置值的设置机器字长为 n 时,偏置值 = 2n12^{n-1}
真值最小值2n1-2^{n-1} → 移码 = 00
真值最大值2n112^{n-1}-1 → 移码 = 2n12^n-1

移码是 IEEE 754 浮点数的基础,详见 浮点数和 IEEE 754

数据的宽度和存储#

常见的数据类型与宽度#

C 语言中基本数据类型的典型宽度(以 32/64 位通用平台为准):

类型charshortintfloatdouble
字节数1 B2 B4 B4 B8 B
位数8 bit16 bit32 bit32 bit64 bit

unsigned 仅表示无符号,不改变数据宽度——宽度由后面的类型决定。例如 unsigned int 仍然是 4 字节。

各种”字长”#

1. 机器字长(CPU 字长)#

最核心的概念。指 CPU 一次能处理的二进制位数,等于通用寄存器、ALU、数据总线的宽度。

  • 常说的”32 位 CPU""64 位 CPU”就是指机器字长
  • 机器字长越长,单次运算能处理的数据越大,寻址范围也越大

2. 存储字长#

一个存储单元中存放的二进制位数。通常与机器字长相等,但不一定。

  • 存储字长 = 机器字长 → 一个存取周期就能读写一个完整的机器字
  • 主存常按字节编址(每个地址对应 8 位),但一次读出可能是 32 或 64 位

3. 指令字长#

一条指令的二进制位数。

  • 定长指令字:所有指令长度相同(如 MIPS 固定 32 位)
  • 变长指令字:不同指令长度不同(如 x86,指令从 1 字节到 15 字节)
  • 指令字长可以是机器字长的整数倍,也可以不是

4. 数据字长#

数据总线上一次传输的二进制位数,通常等于机器字长。

总结对比#

名称含义典型值 (64位机)
机器字长CPU一次处理的位数64 bit
存储字长存储单元存放的位数64 bit(常对齐)
指令字长一条指令的位数不定(x86变长)
数据字长数据总线一次传的位数64 bit

关键区别:机器字长是 CPU 决定的”能力上限”;指令字长取决于指令集设计,可以和机器字长不同;存储字长取决于存储器设计。

字节顺序(端序)#

多字节数据在内存中的存放顺序有两种策略。以 int x = 12345678H(占 4 字节)为例:

大端存储(Big-Endian)#

数据高位放在地址低位,数据低位放在地址高位。

地址0800H0801H0802H0803H
数据12H34H56H78H
  • 最高字节 12H 在最低地址 → 符合人类读写习惯
  • 网络字节序(TCP/IP)采用大端

小端存储(Little-Endian)#

数据高位放在地址高位,数据低位放在地址低位。

地址0800H0801H0802H0803H
数据78H56H34H12H
  • 最低字节 78H 在最低地址 → 便于 CPU 做不同宽度的类型转换
  • x86 / ARM(默认)采用小端

关键:字节序只影响字节之间的排列,一个编址单位(1 字节)内部的 bit 顺序不受影响。78H 无论在哪个地址,其内部 bit 排列不变。

数据表示
https://dongyanzhang.com/posts/计算机组成原理/数据表示/
作者
阿东阿言
发布于
2026-07-14
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
阿东阿言
I share my notes | projects | experience here...
公告
欢迎来到阿东阿言的博客
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
分类
标签
站点统计
文章
25
分类
3
标签
5
总字数
11,186
运行时长
0
最后活动
0 天前
站点信息
构建平台
Local
博客版本
v1.0.0
文章许可
CC BY-NC-SA 4.0