数据表示与运算

📅 2026/8/1 1:55:08 👁️ 阅读次数 📝 编程学习
数据表示与运算

数据表示与运算

🎯核心目标:掌握计算机如何用二进制表示各种数据(整数、小数、字符),以及ALU如何进行算术和逻辑运算。


一、为什么计算机使用二进制?

💡核心原因:二进制最简单、最可靠、最物理可实现。

原因解释
物理实现简单电路只需两种状态:高电平(1) / 低电平(0),可用电压、电流、磁化方向表示
运算规则简单二进制加法只有4种组合,比十进制简单得多
抗干扰能力强两种状态区分度大,即使信号有一定衰减也能正确识别
逻辑门实现方便与布尔代数完美对应:真/假 = 1/0

🔑关键认识:计算机内部所有数据——数字、文字、图像、音频、视频——本质上都是0和1的序列


二、进制转换

1. 常见进制

进制前缀/后缀示例应用场景
二进制0b/B0b1010计算机内部
八进制0/O017Unix文件权限
十进制无 /D13人类日常
十六进制0x/H0xFF内存地址、颜色编码

2. R进制 ↔ 十进制

R进制 → 十进制:按权展开求和

(1011.01)₂ = 1×2³ + 0×2² + 1×2¹ + 1×2⁰ + 0×2⁻¹ + 1×2⁻² = 8 + 0 + 2 + 1 + 0 + 0.25 = 11.25

十进制 → R进制:整数部分除R取余(倒序),小数部分乘R取整(正序)

将 13.625 转为二进制: 整数部分:13 ÷ 2 = 6 余 1 6 ÷ 2 = 3 余 0 3 ÷ 2 = 1 余 1 1 ÷ 2 = 0 余 1 → 倒序:1101 小数部分:0.625 × 2 = 1.25 → 取整 1 0.25 × 2 = 0.5 → 取整 0 0.5 × 2 = 1.0 → 取整 1 → 正序:101 结果:(13.625)₁₀ = (1101.101)₂

⚠️注意:有些小数无法精确转换(如0.1),会在有限位数后截断,导致浮点数精度问题。

3. 二进制 ↔ 八进制/十六进制

  • 二进制→八进制:每3位一组(整数左补零,小数右补零)
  • 二进制→十六进制:每4位一组
(110101110.101)₂ → 八进制:110 101 110 . 101 → (656.5)₈ → 十六进制:0001 1010 1110 . 1010 → (1AE.A)₁₆

三、定点数的表示

定点数:小数点位置固定。分为定点整数定点小数

1. 真值与机器数

  • 真值:实际数值(带正负号),如 +13、-7.5
  • 机器数:计算机中存储的二进制表示(用符号位表示正负)

2. 无符号数

  • 所有位都表示数值,没有符号位
  • 8位无符号数范围:0 ~ 255(0 ~ 2⁸-1)
  • n位无符号数范围:0 ~ 2ⁿ-1

3. 有符号数的表示方法

原码(Sign-Magnitude)
  • 最高位为符号位(0正1负),其余为数值位
  • 例:+5 =0,0000101,-5 =1,0000101
  • 缺点:零有两种表示(+0和-0);加减运算需要额外判断符号
反码(One’s Complement)
  • 正数:与原码相同
  • 负数:符号位不变,数值位按位取反
  • 例:-5 =1,1111010
  • 缺点:零仍有两种表示;运算时需处理循环进位
补码(Two’s Complement)⭐⭐⭐

🔑最重要、最常用:现代计算机中,整数统一使用补码表示和运算。

  • 正数:与原码相同
  • 负数:反码 + 1(或:模 - 真值)
  • 例:-5 的补码:原码1,0000101→ 反码1,1111010→ 补码1,1111011
  • 优点:零唯一表示;加减法统一;符号位参与运算无需单独处理

补码求法速记

方法1:原码 → 反码(除符号位取反) → +1 方法2:从右往左,找到第一个1,它左边所有位取反(符号位除外) 方法3:模运算(2ⁿ - |真值|)
移码(Excess-N / Offset Binary)
  • 用于浮点数的阶码表示
  • 定义:移码 = 真值 + 偏移量(通常为 2ⁿ⁻¹)
  • 特点:便于比较大小(与无符号数的顺序一致)
  • 例:8位移码,偏移量128,+5 =10000101(即128+5=133)

4. 三种表示法的对比

真值原码反码补码
+50,00001010,00001010,0000101
-51,00001011,11110101,1111011
+00,00000000,00000000,0000000
-01,00000001,11111110,0000000(与+0相同)✓

5. 定点数的范围

n位整数(1位符号 + n-1位数值)

  • 原码/反码:-(2ⁿ⁻¹-1) ~ +(2ⁿ⁻¹-1)
  • 补码:-2ⁿ⁻¹ ~ +(2ⁿ⁻¹-1)
  • 无符号:0 ~ 2ⁿ-1

8位举例

  • 补码:-128 ~ +127
  • 原码:-127 ~ +127
  • 无符号:0 ~ 255

💡补码可以多表示一个负数:因为零唯一,所以-128的补码是10000000


四、定点数的运算

1. 移位运算

移位类型操作符号位空位填充用途
逻辑左移整体左移参与右补0无符号数×2
逻辑右移整体右移参与左补0无符号数÷2
算术左移整体左移不变右补0有符号数×2
算术右移整体右移不变左补符号位有符号数÷2

⚠️算术左移注意:若符号位改变,则发生溢出!

2. 加减运算(补码加减法)⭐⭐⭐

核心公式

[A + B]补 = [A]补 + [B]补 (mod 2ⁿ) [A - B]补 = [A]补 + [-B]补 = [A]补 + [B]补的变补 (mod 2ⁿ)

💡减法变加法:减去一个数 = 加上它的相反数的补码。这样硬件只需实现加法器!

溢出判断

  • 单符号位:两个正数相加得负,或两个负数相加得正 → 溢出
  • 双符号位:运算结果的两个符号位不同 → 溢出(01正溢,10负溢)
  • 进位判断:最高数值位进位 ⊕ 符号位进位 = 1 → 溢出

3. 乘法运算

原码乘法
  • 符号位单独处理(异或),数值部分做绝对值乘法
  • 类似十进制竖式乘法:累加+移位
补码乘法(Booth算法)⭐
  • 直接处理补码,无需先转原码
  • 核心思想:利用相邻位的变化来决定加/减/不移位
  • 适合硬件实现,高效
乘法溢出
  • n位数乘n位数,结果可能2n位
  • 若只保留n位,高位丢失 → 溢出

4. 除法运算

原码除法
  • 符号位单独处理,数值做绝对值除法
补码除法(加减交替法)
  • 直接处理补码
  • 核心:根据余数符号决定加除数还是减除数

5. 标志位(条件码)

运算结果会设置标志位,供条件判断使用:

标志位名称含义
ZF零标志结果全为0
SF符号标志结果最高位(补码即符号位)
CF进位/借位标志无符号数运算溢出
OF溢出标志有符号数运算溢出
PF奇偶标志结果低8位中1的个数为偶数
AF辅助进位低4位向高4位进位

五、浮点数的表示(IEEE 754标准)⭐⭐⭐

🔑 浮点数 = 科学计数法的二进制版:N = (-1)ˢ × 1.M × 2ᴱ⁻¹²⁷

1. 浮点数的格式

┌───┬──────────┬──────────────────────────────┐ │ S │ E │ M (尾数/有效数) │ │ 1位│ 指数位 │ 尾数位 │ └───┴──────────┴──────────────────────────────┘
精度总位数符号位指数位尾数位偏移量
单精度(float)321823127
双精度(double)64111521023

2. 规格化表示

  • 尾数最高位恒为1(隐含),所以实际精度比位数多1
  • 单精度:实际精度24位;双精度:实际精度53位
  • 规格化范围:1 ≤ |M| < 2

3. 特殊值

指数(E)尾数(M)含义
全0全0±0
全0非0非规格化数(非常小的数)
1~254任意规格化数
全1全0±∞(正负无穷)
全1非0NaN(非数字)

4. 浮点数运算步骤

  1. 对阶:将指数较小的数调整为与较大的数相同(尾数右移)
  2. 尾数运算:加减
  3. 规格化:确保尾数在 [1, 2) 范围内
  4. 舍入:按规则截断或进位
  5. 溢出判断:阶码是否超出范围

⚠️经典陷阱0.1 + 0.2 ≠ 0.3(在浮点数中),因为0.1无法精确表示为二进制浮点数!


六、字符与字符串的编码

1. ASCII编码

  • 7位编码,128个字符(0~127)
  • 包括:控制字符(0~31)、数字、字母、标点
  • 扩展ASCII:8位,256个字符(含欧洲语言符号)

2. Unicode

  • 统一字符编码,覆盖全球所有语言
  • UTF-8:变长编码(1~4字节),兼容ASCII,互联网主流
  • UTF-16:变长编码(2或4字节),Java/C#内部使用
  • UTF-32:定长4字节

3. 汉字的表示

  • GB2312:6763个汉字,双字节
  • GBK:21003个汉字,向下兼容GB2312
  • GB18030:27484个汉字,兼容GBK
  • Unicode:统一编码,CJK统一汉字

4. 字符串的存储

  • C语言:以\0结尾的字符数组
  • 其他方式:长度前缀 + 字符数组
  • 大端/小端:多字节字符在内存中的字节顺序

5. 大端 vs 小端 ⭐

方式含义举例(0x12345678)
大端(Big-Endian)高位字节存放在低地址12 34 56 78(人类阅读习惯)
小端(Little-Endian)低位字节存放在低地址78 56 34 12(x86架构)

💡记忆法:大端 = 大端在前(高位在前);小端 = 小端在前(低位在前)。x86 CPU是小端,网络传输通常大端。


七、校验码

1. 奇偶校验码

  • 在数据后添加1位校验位,使1的个数为奇数(奇校验)或偶数(偶校验)
  • 只能检测奇数个位错误,不能纠错

2. 海明码(Hamming Code)

  • 可检测并纠正1位错误
  • 核心:在2的幂次位置(1,2,4,8…)放置校验位
  • 校验位覆盖特定位置的数据位
  • 若需检测d位错、纠正c位错,需满足:2ʳ ≥ d + c + 1(r为校验位位数)

3. 循环冗余校验(CRC)⭐

  • 用于数据传输和存储的检错
  • 将数据视为多项式,除以生成多项式,余数作为校验码
  • 检错能力强,能检测多位错误和突发错误
  • 硬件实现简单(移位寄存器+异或门)

八、重点回顾

重点一句话总结
进制转换整数除R取余,小数乘R取整;二-八进制3位一组,二-十六进制4位一组
原码符号位+数值位,零不唯一,加减复杂
反码负数数值取反,零不唯一,需循环进位
补码负数反码+1,零唯一,加减统一,符号位参与运算
移码真值+偏移量,用于浮点阶码,便于比较
浮点数IEEE 754:符号位 + 阶码 + 尾数,注意规格化和特殊值
大小端大端高位在前(网络),小端低位在前(x86)
校验码奇偶校验(检错)、海明码(纠错)、CRC(强检错)

📌下章预告:我们将探索计算机的"记忆系统"——存储器层次结构。从高速昂贵的寄存器到海量便宜的磁盘,了解Cache如何让你的程序飞起来!