02

编码与组合

信息的表示

阅读量:2 · 预计 16 分钟读完

摩尔斯电码盲文二进制
关联层级:L1 基础逻辑门
阅读进度7%

第二章 编码与组合 — 信息的表示

导读

我们生活在一个被信息包围的世界。每一条微信消息、每一首音乐、每一张照片、每一段视频,在计算机的眼中都不过是一串由0和1组成的数字序列。但一个根本性的问题随之而来:计算机是如何用简单的0和1来表示如此丰富多彩的信息的?一个数字、一个字母、一种颜色、一段声音,它们是如何被"翻译"成计算机能够处理的形式的?

答案就是编码(Encoding)。编码是将信息从一种形式转换为另一种形式的过程,它是人类与计算机之间、计算机各组成部分之间沟通的桥梁。从最基础的数字表示到复杂的字符编码,从简单的颜色量化到精密的声音采样,编码无处不在,却又常常隐匿于幕后,不被普通用户所察觉。

本章将系统地介绍信息编码的基本原理和方法。我们将从数制转换开始,理解计算机为什么选择二进制;然后探讨整数的多种表示方法,理解为什么计算机中的减法可以用加法来实现;接着深入字符编码的世界,从ASCII到Unicode,看人类如何让计算机理解全世界的文字;最后,我们将了解声音和图像是如何被数字化编码的。通过本章的学习,你将掌握信息表示的核心机制,为理解计算机的底层工作原理打下坚实的基础。

核心概念详解

2.1 数制:信息的数学表示

数制(Number System)是用一组固定的符号和统一的规则来表示数值的方法。我们日常生活中最常用的是十进制(Base-10),使用0到9共十个数字。但十进制并非唯一的选择,也不是最"自然"的选择——它之所以成为主流,仅仅是因为人类有十根手指。

二进制(Base-2)使用0和1两个数字。每一位的权值是2的幂次:从右到左依次是2⁰=1, 2¹=2, 2²=4, 2³=8, 2⁴=16...。例如,二进制数1101表示:1×2³ + 1×2² + 0×2¹ + 1×2⁰ = 8 + 4 + 0 + 1 = 13。

八进制(Base-8)使用0到7共八个数字,每一位的权值是8的幂次。十六进制(Base-16)使用0到9和A到F共十六个符号(A=10, B=11, C=12, D=13, E=14, F=15),每一位的权值是16的幂次。

为什么计算机选择二进制?根本原因在于物理实现的简便性。在电子电路中,最容易区分和稳定维持的状态是两种:高电平和低电平、导通和截止、有电流和无电流。这两种状态恰好对应二进制的0和1。如果使用十进制,电路需要精确区分十个不同的电压等级,这在工程上极其困难,而且容易受到噪声干扰。

二进制还有一个重要的数学优势:运算规则极其简单。加法只有四种基本组合(0+0=0, 0+1=1, 1+0=1, 1+1=10),乘法也只有四种(0×0=0, 0×1=0, 1×0=0, 1×1=1)。这种简单性使得硬件电路的设计大大简化。

2.2 数制转换

掌握不同数制之间的转换,是理解计算机信息表示的基础。

二进制转十进制:将每一位数字乘以对应的权值,然后求和。例如:

  • 1011₂ = 1×2³ + 0×2² + 1×2¹ + 1×2⁰ = 8 + 0 + 2 + 1 = 11₁₀
  • 110.101₂ = 1×2² + 1×2¹ + 0×2⁰ + 1×2⁻¹ + 0×2⁻² + 1×2⁻³ = 4 + 2 + 0 + 0.5 + 0 + 0.125 = 6.625₁₀

十进制转二进制:整数部分使用"除2取余"法,小数部分使用"乘2取整"法。

  • 整数转换: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)。从上往下读取整数部分:0.101。

二进制与十六进制的互转:由于16 = 2⁴,每4位二进制恰好对应1位十六进制,转换非常便捷。

  • 1101 0110₂ = D6₁₆(1101=D, 0110=6)
  • 3F₁₆ = 0011 1111₂(3=0011, F=1111)

这种便捷的转换关系使得十六进制成为表示二进制数据的理想工具:它比二进制更紧凑(4位缩为1位),又比十进制更直观地反映二进制的位模式。

2.3 整数的表示

在计算机中,整数有几种不同的表示方法,每种方法都有其特定的优缺点。

原码(Sign-Magnitude):最高位为符号位(0表示正,1表示负),其余位表示数值的绝对值。例如,在8位表示中:

  • +5 = 0000 0101
  • -5 = 1000 0101

原码的优点是直观易懂,但有两个严重缺点:一是零有两种表示(+0 = 0000 0000 和 -0 = 1000 0000),二是加减法需要分别处理符号和数值,硬件实现复杂。

反码(Ones' Complement):正数的反码与原码相同;负数的反码是将原码的数值位全部取反。例如:

  • +5 = 0000 0101
  • -5 = 1111 1010

反码解决了原码中减法运算的部分问题(减法可以转化为加法),但仍然存在零的双重表示问题(+0 = 0000 0000, -0 = 1111 1111)。

补码(Two's Complement):正数的补码与原码相同;负数的补码是反码加1。例如:

  • +5 = 0000 0101
  • -5 = 1111 1011

补码是现代计算机中表示整数的标准方式,它有三个重要优势:

零的唯一表示:0 = 0000 0000,不存在-0的问题

加减统一:加法和减法可以使用同一套加法电路实现,不需要额外的减法器

溢出自然:超出表示范围的溢出位被自然丢弃,结果仍然正确

补码的第三个优势值得深入理解。在8位补码系统中,表示范围是-128到+127。计算 5 + (-3):

0000 0101  (+5)
+ 1111 1101  (-3)
= 0000 0010  (+2),进位被丢弃

结果正确!这就是补码的魔力:减法可以通过加法来实现,硬件只需要一个加法器就够了。

2.4 浮点数的表示

整数只能表示离散的数值,但现实世界中很多量是连续的——长度、温度、时间。为了在计算机中表示实数,需要使用浮点数(Floating-Point Number)。

现代计算机普遍采用IEEE 754标准来表示浮点数。该标准定义了两种基本格式:

单精度(32位):1位符号位 + 8位指数位 + 23位尾数位

双精度(64位):1位符号位 + 11位指数位 + 52位尾数位

浮点数的值可以表示为:(-1)^S × 1.M × 2^(E-bias)

其中S是符号位,M是尾数(小数部分),E是指数,bias是偏移量(单精度为127,双精度为1023)。

例如,十进制数6.625用单精度浮点数表示:

符号位:正数,S = 0

整数部分:6 = 110₂

小数部分:0.625 = 0.101₂

合并:110.101₂ = 1.10101₂ × 2²

指数:E = 2 + 127 = 129 = 10000001₂

尾数:M = 10101000000000000000000(省略前导1)

最终表示:0 10000001 10101000000000000000000

浮点数的一个重要特性是精度有限。单精度浮点数大约能提供7位有效十进制数字,双精度大约能提供15-16位。这意味着某些十进制数在浮点数表示中会产生微小的误差。例如,0.1在二进制中是一个无限循环小数,无法被精确表示。这就是为什么在编程中 0.1 + 0.2 的结果可能是 0.30000000000000004 而不是精确的 0.3。

2.5 字符编码

计算机只能处理数字,但人类使用文字。字符编码就是将文字映射为数字的方案。

ASCII码(American Standard Code for Information Interchange)是最早被广泛采用的字符编码标准。它使用7位二进制数(共128个编码)来表示英文字母、数字、标点符号和一些控制字符。例如:

  • 'A' = 65 = 01000001
  • 'a' = 97 = 01100001
  • '0' = 48 = 00110000
  • 空格 = 32 = 00100000

ASCII码的设计有一个巧妙的特性:大写字母和小写字母的编码只差32(即第6位不同),这使得大小写转换只需要翻转一个位。数字'0'到'9'的编码是连续的(48到57),这简化了数字字符和数值之间的转换。

ASCII码的128个编码足以覆盖英文,但远远不够表示世界上其他语言的文字。中文有数万个汉字,日文包含假名、汉字和罗马字,阿拉伯文从右到左书写……为了统一表示全世界的文字,Unicode应运而生。

Unicode为世界上每一个字符分配一个唯一的编号(称为码点,Code Point),范围从U+0000到U+10FFFF,共约110万个码点。目前Unicode已经收录了超过14万个字符,覆盖了现代和历史上几乎所有主要的书写系统。

但Unicode本身只是一个字符集(Character Set),它定义了字符和码点之间的映射关系,并没有规定码点在计算机中如何存储。实际的存储方案由编码方案(Encoding Scheme)来定义,最常见的有:

  • UTF-8:变长编码,使用1到4个字节表示一个字符。ASCII字符仍然使用1个字节(与ASCII兼容),中文常用字符使用3个字节。UTF-8是互联网上最广泛使用的编码方案。
  • UTF-16:使用2或4个字节表示一个字符。Java和Windows内部使用UTF-16。
  • UTF-32:每个字符固定使用4个字节。简单直接但空间效率低。

2.6 声音的数字化

声音是一种连续的机械波,要将它存储在计算机中,需要将其转换为数字形式。这个过程称为模数转换(Analog-to-Digital Conversion, ADC),主要包括两个步骤:采样(Sampling)量化(Quantization)

采样是在时间轴上对连续信号进行离散化。根据奈奎斯特采样定理(Nyquist Theorem),采样频率必须至少是信号最高频率的两倍,才能无失真地还原原始信号。人耳能听到的频率范围大约是20Hz到20kHz,因此CD音质的采样频率定为44.1kHz(略高于20kHz的两倍)。

量化是在幅度轴上对采样值进行离散化。每个采样值被近似为最接近的量化级别。量化级别的多少由量化位数决定:8位量化有256个级别,16位量化有65536个级别。CD音质使用16位量化。

将采样频率和量化位数结合起来,就可以计算数字音频的数据量。例如,CD音质(44.1kHz采样,16位量化,立体声双声道)的数据量为:

44100 × 16 × 2 = 1,411,200 位/秒 ≈ 176 KB/秒

这就是为什么未压缩的音频文件(如WAV格式)体积较大,而MP3、AAC等压缩格式通过去除人耳不敏感的信息来大幅减小文件体积。

2.7 图像的数字化

图像的数字化比声音更加直观。一幅数字图像可以被看作一个二维网格,每个网格单元称为一个像素(Pixel),每个像素存储颜色和亮度信息。

位图图像直接记录每个像素的颜色值。颜色表示方式有多种:

  • 灰度图像:每个像素用8位表示,可以表示256个灰度级别(0=黑色,255=白色)
  • RGB彩色图像:每个像素用三个8位值分别表示红(R)、绿(G)、蓝(B)三个通道的强度,共可以表示256×256×256 ≈ 1677万种颜色
  • RGBA图像:在RGB基础上增加一个Alpha通道表示透明度

一幅1920×1080的RGB图像,每个像素3字节,总数据量为:

1920 × 1080 × 3 = 6,220,800 字节 ≈ 5.93 MB

这就是为什么图像文件通常需要压缩。JPEG使用有损压缩(去除人眼不敏感的细节),PNG使用无损压缩(利用像素之间的相关性)。

矢量图像采用完全不同的方式:它不记录每个像素的颜色,而是用数学公式描述图形的几何特征(点、线、曲线、多边形等)。矢量图像可以无限放大而不失真,但难以表现照片级的复杂图像。

重要知识点

知识点一:二进制是计算机的基础

计算机选择二进制不是偶然的,而是由物理实现的简便性和数学运算的简单性共同决定的。理解二进制是理解计算机工作原理的第一步。

知识点二:补码的精妙设计

补码使得加法和减法可以使用同一套硬件电路实现,零有唯一的表示,溢出处理自然。这些特性使得补码成为现代计算机表示整数的标准方式。

知识点三:浮点数的精度限制

浮点数只能近似表示实数,精度有限。在需要精确计算的场景(如金融计算)中,应使用定点数或专门的十进制运算库。

知识点四:UTF-8是互联网的标准编码

UTF-8的设计兼顾了兼容性和效率:与ASCII兼容,对英文文本空间效率高,同时能够表示Unicode中的所有字符。

知识点五:采样定理

奈奎斯特采样定理是数字信号处理的基石:采样频率必须至少是信号最高频率的两倍。这个定理决定了音频、视频等数字媒体的基本参数。

常见误区

误区一:"1KB = 1000字节"

在计算机科学中,1KB传统上等于1024字节(2¹⁰),而不是1000字节。这是因为计算机使用二进制,2的幂次比10的幂次更自然。不过,硬盘制造商通常使用1KB = 1000字节来标注容量,这就是为什么购买的硬盘实际容量总是比标注的小一些。为了消除歧义,国际电工委员会(IEC)定义了二进制前缀:1KiB = 1024字节,1MiB = 1024KiB。

误区二:"浮点数运算是精确的"

浮点数运算存在精度误差,这是由浮点数的表示方式决定的。例如:

0.1 + 0.2 = 0.30000000000000004(而非0.3)
1.0 / 3.0 = 0.3333333333333333(而非0.333...)

在比较浮点数时,不应使用 == 运算符,而应检查两个数的差值是否小于一个很小的阈值(epsilon)。

误区三:"Unicode就是UTF-8"

Unicode是字符集,定义了字符和码点的映射;UTF-8是编码方案,定义了码点在计算机中的存储方式。两者是不同的概念。除了UTF-8,还有UTF-16、UTF-32等编码方案。

误区四:"图像分辨率越高越好"

更高的分辨率意味着更多的像素和更大的文件体积,但并不总是意味着更好的视觉效果。在屏幕尺寸和观看距离固定的情况下,超过一定分辨率后,人眼无法分辨差异,反而浪费了存储空间和传输带宽。

实践应用

应用一:手动进行数制转换

练习将以下数字在不同数制之间转换:

  • 十进制 255 → 二进制、八进制、十六进制
  • 二进制 1010 1100 → 十进制、十六进制
  • 十六进制 3B → 二进制、十进制

应用二:理解文件编码

使用文本编辑器打开一个文件,查看其编码方式。尝试将同一个中文文本分别保存为UTF-8、GBK、UTF-16编码,比较文件大小。你会发现UTF-8编码的文件通常比UTF-16小,因为UTF-8对中文字符使用3个字节,而UTF-16使用2或4个字节。

应用三:计算音频文件大小

计算以下场景的未压缩音频文件大小:

  • 电话音质:8kHz采样,8位量化,单声道,时长3分钟
  • 录音棚音质:96kHz采样,24位量化,立体声,时长5分钟

应用四:探索补码运算

在8位补码系统中,验证以下运算:

  • 7 + (-3) = 4
  • (-5) + (-8) = -13
  • 100 + 50 = 150(观察溢出)

本章小结

本章系统地介绍了信息编码的基本原理和方法:

数制与转换:二进制是计算机的基础,十六进制是二进制的紧凑表示。掌握数制转换是理解计算机信息表示的前提。

整数表示:补码是现代计算机表示整数的标准方式,它使加减法统一,零有唯一表示。

浮点数表示:IEEE 754标准定义了浮点数的格式,精度有限是浮点运算的固有特性。

字符编码:从ASCII到Unicode,人类让计算机理解了全世界的文字。UTF-8是互联网上最广泛使用的编码方案。

声音数字化:通过采样和量化,连续的声波被转换为离散的数字序列。采样定理是数字信号处理的基石。

图像数字化:位图记录每个像素的颜色值,矢量图用数学公式描述图形。

编码是连接人类世界和计算机世界的桥梁。在下一章中,我们将深入探讨二进制编码的具体应用——布莱叶盲文,以及它如何启发了现代数字编码的思想。