计算机科学基础/信息表示
计算机通常将颜色表示为一个红-绿-蓝 (RGB) 数值集,称为“三元组”,其中红色、绿色和蓝色分量都是 0 到 255 之间的整数。例如,颜色 (255, 0, 10) 具有全红色、无绿色和少量蓝色。编写一个算法,该算法以颜色的 RGB 分量作为输入,并返回一个消息,指示最大分量或分量。例如,如果输入颜色为 (100, 255, 0),则算法应输出“最大分量(s):绿色”。如果输入颜色为 (255, 255, 255),则算法应输出“最大分量(s):红色、绿色、蓝色".
计算机的一个惊人之处在于它们可以存储如此多的不同类型的数据。当然计算机可以存储数字。但与简单的计算器不同,它们还可以存储文本,并且可以存储颜色、图像、音频、视频以及许多其他类型的数据。而且它们不仅可以存储多种类型,还可以分析它们,并将它们传输到其他计算机。这种多功能性是计算机如此有用并影响我们生活如此多领域的原因之一。
要了解计算机和计算机科学,重要的是要了解计算机如何处理不同类型的数据。让我们回到颜色。颜色是如何存储在计算机中的?介绍性问题陈述了一种方法:作为 RGB 三元组。这不是唯一可能的方法。RGB 只是众多颜色系统之一。例如,有时颜色用 HSV 三元组表示:通过色调、饱和度和亮度。然而,RGB 是计算机程序中最常见的颜色表示。
这导致了一个更深层次的问题:计算机是如何存储数字的?为什么我们必须了解数字和其他不同类型的数据是如何在计算机中存储和处理的?本章讨论了这些问题以及相关问题。特别是,我们将看看以下内容
- 为什么这是一个重要的主题?
- 计算机如何表示数字?
- 计算机如何表示文本?
- 计算机如何表示其他类型的数据,例如图像?
- 什么是二进制数系,为什么它在计算机科学中很重要?
- 计算机如何进行基本运算,如加法和减法?
完成本章后,您应该能够执行以下操作
- 能够解释计算机在最低级别上如何表示数值数据和文本数据,以及其他类型的数据,例如颜色数据。
- 能够解释和使用该领域的基本术语:位、字节、兆字节、RGB 三元组、ASCII 等。
- 能够将数字和文本从一种表示形式转换为另一种表示形式。
- 能够将整数从一种表示形式转换为另一种表示形式,例如从十进制表示形式转换为二进制补码表示形式。
- 能够对无符号二进制或二进制补码表示形式的数字进行加减运算。
- 能够解释用于表示数据的位数如何影响表示的范围和精度。
- 能够一般性地解释计算机如何表示不同类型的数据,例如图像。
- 能够进行涉及某些数据集的内存量或下载时间的计算。
数据表示与博雅教育和数学有什么关系?正如您可能猜到的那样,它们之间有着密切的联系。计算机将所有数据存储为二进制(即以 2 为底)数字。因此,要了解计算机,就必须了解二进制。此外,您不仅需要了解二进制基础知识,还需要了解一些复杂之处,例如下面讨论的“二进制补码”表示法。
二进制表示之所以重要,不仅因为它描述了计算机如何表示数据,而且因为计算机和计算的很大一部分都基于它。例如,我们将在关于机器组织的章节中再次看到它。
计算机革命。您经常听到这个词来形容计算机影响我们生活的方式。另一个您可能听到的词是数字革命。数字革命是什么意思?
如今,我们许多设备都是数字化的。我们有数字手表、数字手机、数字收音机、数字电视等。然而,以前许多设备是模拟的:“数据……由连续变化的物理量表示”[1] 例如,想想那些具有秒针、分针和时针的老式手表,这些指针连续移动(尽管分针和时针移动得很慢)。将其与许多现代手表进行比较,现代手表显示时间的数字表示形式,例如 2:03:23。
此示例突出了模拟设备和数字设备之间的关键区别:模拟设备依赖于连续现象,而数字设备依赖于离散现象。作为这种差异的另一个例子,模拟收音机接收音频广播信号,这些信号作为无线电波传输,而数字收音机接收的信号是数字流。[2]
数字革命指的是许多数字设备、它们的用途及其影响。这些设备不仅包括计算机,还包括在我们生活中发挥重要作用的其他设备或系统,例如通信系统。
由于数字设备通常使用二进制数系统存储数字,因此本章的一个主要主题是数据的二进制表示。二进制是计算机和计算机科学的基础:要了解计算机的工作原理以及计算机科学家的思维方式,您需要了解二进制。因此,本章的第一部分将介绍二进制基础知识。第二部分在此基础上构建,并解释计算机如何存储不同类型的数据。
计算从根本上来说是关于信息处理的。每次计算都是对符号的某种操作,这种操作可以纯粹机械地(盲目地)完成。如果我们可以使用符号表示信息,并知道如何处理这些符号并解释结果,我们就可以访问有价值的新信息。在本节中,我们将研究计算中的信息表示。
算法章节讨论了描述操作序列的方法。计算机科学家使用算法来指定计算机的行为。但是,为了使这些算法有用,它们需要数据,因此计算机需要能够表示数据。[3]
信息作为消息的内容传达,当我们用感官解释和感知这些消息时,会导致某些心理反应。信息总是被编码成某种形式以进行传输和解释。我们一直都在处理信息。例如,我们在阅读书籍、听故事、看电影或做梦时会接收信息。我们在写电子邮件、画画、在表演中表演或发表演讲时会提供信息。信息是抽象的,但它通过具体的媒介传达。例如,电话上的对话会传递信息,但信息在传播过程中由声波和电子信号表示。
信息是抽象的/虚拟的,而承载信息的媒介必须是具体的/物理的。因此,在任何信息可以被处理或传递之前,它必须被量化/数字化:这是一个将信息转换为使用符号的(数据)表示的过程。
人们有许多方法来表示一个非常简单的数字。例如,数字 4 可以表示为 4 或 IV 或||||或 2 + 2,等等。计算机如何表示数字?(或文本?或音频文件?)
计算机表示和处理数字的方式与我们不同。自早期计算机历史以来,二进制数系统一直是标准。计算机“喜欢”二进制,因为这对它们来说非常容易。然而,二进制对人类来说并不容易。虽然大多数时候人们不需要关心计算机使用的内部表示,但有时他们确实需要。
假设你和一些朋友在周末去小屋度假。这群人将乘坐两辆不同的汽车前往,你们都同意第一组到达的人将留下前灯打开,以便后面一组更容易找到。当您乘坐的汽车到达小屋时,您可以通过灯光判断您的汽车是否先到达。因此,灯光编码了两种可能性:开(另一组已经到达)或关(另一组尚未到达)。
为了传递更多信息,您可以使用两盏灯。例如,两盏灯都关表示第一组尚未到达,第一盏灯关第二盏灯开表示第一组已经到达,但离开了去采购,第一盏灯开第二盏灯关表示这组已经到达,但离开了去钓鱼,两盏灯都开表示这组已经到达,并且没有离开。
注意这里的关键思想:一盏灯可以开或关(我们不允许不同的灯光级别、多种颜色或其他选项),只有两种可能性。但第二个是,如果我们要表示超过两个选择,我们可以使用更多灯。
这种“开或关”的理念是一个强大的理念。有两个且只有两个不同的选择或状态:开或关、0 或 1、黑或白、存在或不存在、大或小、粗糙或光滑,等等——所有这些都是表示可能性的不同方式。双重选择理念如此强大的一个原因是,更容易构建数据在最低级别处于两种可能状态的对象——计算机、相机、CD,等等,无论是 0 还是 1。[4]
在计算机表示中,一个位(即二进制数字)可以是 0 或 1。位集合称为位串。一个 8 位长的位串称为字节。位和字节是计算机存储和数据传输中的重要概念,稍后我们将进一步解释它们以及一些相关的术语和概念。但首先我们将研究计算机如何表示数字的基本问题。
克劳德·香农被认为是信息论之父,因为他第一个研究并构建了信息和信息传递的数学模型。他还对计算做出了许多其他重要贡献。他具有开创性的论文“通信的数学理论”(1948 年)改变了我们对信息的看法,为信息时代奠定了基础。香农发现信息的根本单位是对一个问题的肯定或否定答案,或一个具有两个不同状态的比特,它只能用两个符号来表示。他还通过证明布尔代数的命题可以用来构建能够执行一般计算(对两种类型符号的操作)的“逻辑机器”,奠定了数字计算机/电路的设计理论。 数据是另一个与信息密切相关的术语,它是对信息表示的抽象概念。我们将交替使用信息表示和数据。
信息可以在不同的级别表示。将信息表示分为两类是有帮助的:外部表示和内部表示。外部表示用于人机之间的通信。我们在计算机显示器或屏幕上看到的一切,无论是文本、图像还是动态图片,都是某些信息的表示。计算机还使用声音和其他媒介来外部表示信息,例如盲人使用的触摸板来阅读文本。
在内部,所有现代计算机都将信息表示为位。我们可以将位视为一个具有两个可能值的数字。由于位是信息的基本单位,因此它足以表示所有信息。它也是最简单的表示,因为只需要两个符号就可以表示两个不同的值。这使得用物理方式表示位变得很容易——任何能够具有两种不同状态的设备都可以使用,例如一个切换开关。我们将在后面看到,现代计算机处理器是由称为晶体管的微型开关组成的。
当位组合成序列时,它们可以表示数字。我们熟悉用数字来表示数量。数字是表示抽象数量的具体符号。人类有十根手指,方便地采用了十进制(十进制)记数系统,它需要十个不同的符号。我们都了解十进制表示,并且每天都在使用它。例如,阿拉伯数字使用 0 到 9。每个符号表示十的幂,具体取决于符号所处的位置。
因此,例如,数字一百二十四是 。我们可以通过在 124 中的数字上方写出 10 的幂来强调这一点
10^2 10^1 10^0 1 2 4
因此,如果我们利用对十进制的了解并将其应用于二进制,我们可以弄清楚二进制。但首先请记住,一个位是一个二进制数字,一个字节是 8 位。在本文件中,我们谈论的大多数二进制数都将是一字节长。
(计算机实际上使用不止一个字节来表示大多数数字。例如,大多数数字实际上是用 32 位(4 字节)或 64 位(8 字节)来表示的。位数越多,可以表示的不同值就越多:一位允许 2 个值,两位给出 4 个值,三位给出 8 个值,...,八位给出 256 个值,一般来说,n 位给出 个值。然而,在查看二进制示例时,我们通常会使用 8 位数字来使示例易于管理。
十进制系统用于数字表示是某种程度上任意的。事实上,我们经常使用其他进制系统来表示不同性质的数量:一周中的天数使用 7 进制,一小时中的分钟使用 60 进制,一天中的小时使用 24 进制,一磅中的盎司使用 16 进制等等。不难想象,2 进制(两个符号)是最简单的进制系统,因为在少于两个符号的情况下,我们无法表示变化(因此没有信息)。
无符号二进制
[edit | edit source]当我们谈论十进制时,我们处理的是 10 个数字 - 0 到 9(这就是 decimal 的由来)。在二进制中我们只有两个数字,这就是为什么它是 binary。二进制中的数字是 0 和 1。你永远不会看到任何 2 或 3 等等。如果你看到了,那就说明有问题。一个比特总是 0 或 1。
二进制计数如下
0 (decimal 0) 1 (decimal 1) 10 (decimal 2) 11 (decimal 3) 100 (decimal 4) 101 (decimal 5) ...
一个老笑话是,“世界上有 10 种人。懂二进制的和不懂二进制的。”
接下来要考虑的是在一个字节中有哪些值是可能的。让我们列出在一个字节中 2 的幂
2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0 128 64 32 16 8 4 2 1
例如,二进制数 10011001 是 请注意,8 个比特中的每一个都可以是 0 或 1。因此,最左边的比特有两个可能性,下一个比特有两个可能性,再下一个比特有两个可能性,等等:8 个比特中的每一个都有两个选择。将这些可能性相乘,得到 或 256 种可能性。在 无符号二进制 中,这些可能性代表从 0(所有比特为 0)到 255(所有比特为 1)的整数。
所有进制系统的工作原理都是一样的:最右边的数字代表底数的零次方(记住,任何数的零次方都等于 1),左边的每个数字代表的量是右边数字的底数倍。二进制数 1001 代表十进制中的 9,因为最右边的 1 代表 ,零在 和 位置上没有贡献,最后最左边的 1 代表 。当我们使用不同的进制系统时,需要将底数作为下标来表示,以避免混淆。例如,我们写 表示二进制数 1001(代表十进制中的 9)。下标 2 表示“二进制”:它告诉读者它 不 代表十进制中的 1001。这个例子也向我们展示了,表示法本身没有内在意义。相同的符号模式,例如 1001,可以根据其解释方式来代表不同的数量。有许多其他方法来代表数量 (记住:读作“十进制中的九”);例如,汉字 九 代表了同一个数量。
由于同一个数量可以用不同的方式来表示,我们通常可以改变表示方式而不会改变它代表的数量。正如之前所示,二进制表示 等效于十进制表示 - 代表完全相同的值。在学习计算的过程中,我们经常需要在十进制表示法(我们最熟悉)和二进制表示法(计算机内部使用)之间进行转换。
二进制到十进制的转换
[edit | edit source]将非负整数的二进制表示转换为其十进制表示是一个直接的过程:将每个二进制数字代表的数量加起来,就能得到结果。
十进制到二进制转换
[edit | edit source]您将在本书中需要完成一项任务,也是计算机科学家经常需要完成的任务,即在十进制数和二进制数之间进行转换。上一小节展示了如何将二进制转换为十进制:将对应位为 1 的每个 2 的幂相加。
假设我们要进行十进制到二进制的转换。例如,我们将十进制值 75 转换为二进制。这里介绍一种依赖于连续除以 2 的技术。
75/2 quotient=37 remainder=1 37/2 quotient=18 remainder=1 18/2 quotient=9 remainder=0 9/2 quotient=4 remainder=1 4/2 quotient=2 remainder=0 2/2 quotient=1 remainder=0 1/2 quotient=0 remainder=1
然后我们将余数从下到上取,得到 1001011。由于我们通常以 8 位一组进行操作,如果它没有填满所有 8 位,我们在前面添加零直到填满。所以最终得到 01001011。
二进制数学
[edit | edit source]二进制数的加法
[edit | edit source]除了存储数据,计算机还需要进行加法等操作。我们如何在二进制表示中加数字?
位的加法有四个简单的规则,这里用四列垂直表示
0 0 1 1 + 0 + 1 + 0 + 1 ========================= 0 1 1 10
现在,如果我们有一个由多个位组成的二进制数,我们将使用这四个规则,再加上“进位”。以下是一个示例
00110101 + 10101100 ========== 11100001
这是同一个示例,但明确列出了进位,即没有进位时为 0,有进位时为 1。当 1+1=10 时,0 保留在该列的解中,1 进位到左侧的下一列。
0111100 00110101 + 10101100 ========== 11100001
我们可以通过将每个数字转换为十进制来检查二进制运算:在二进制和十进制中,我们对相同的数字执行相同的运算,但使用不同的表示方式。如果表示和运算正确,结果应该一致。让我们再来看一下上面我们刚解决的加法问题。将 转换为十进制得到 (自己进行转换以验证其准确性),将 转换为十进制得到 。将这两个数字相加得到 ,当将其转换回二进制时,确实是 。
但二进制加法并不总是完全正确
01110100 + 10011111 ========== 100010011
注意结果中有 9 位,但一个字节中应该只有 8 位。以下是十进制的总和
116 + 159 ===== 275
注意 275 大于 255,这是我们可以在 8 位数中保存的最大值。这会导致一种称为**溢出**的状况。如果计算机可以转换为 9 位二进制数,溢出就不是问题;但是,如果计算机只为结果保留了 8 位,溢出意味着程序可能无法正常运行甚至无法运行。
二进制数的减法
[edit | edit source]再一次,让我们从查看单个位开始
0 0 1 1 - 0 - 1 - 0 - 1 ======================== 0 -1 1 0
注意在-1情况下,我们通常想要做的是获得 1 结果并借位。因此,让我们将其应用到一个 8 位问题中
10011101 - 00100010 ========== 01111011
这与(以 10 为基数)相同。
157 - 34 ====== 123
以下是二进制减法,借位已显示
1100010 10011101 - 00100010 ========== 01111011
大多数人发现二进制减法比二进制加法困难得多。
与二进制相关的其他表示
[edit | edit source]您可能对上一节中的二进制表示有疑问。例如,负数呢?带小数部分的数字呢?难道所有这些 0 和 1 对人类来说都不难处理吗?这些都是好问题。在本节和其他几个小节中,我们将研究在计算机科学中使用的一些与二进制相关的其他表示方式。
十六进制
[edit | edit source]计算机擅长二进制。人类不擅长。二进制对人类来说很难写、很难读,也很难理解。但是,如果我们想要一种更容易阅读的数字系统,同时又与二进制密切相关,以便保留二进制的一些优点,该怎么办?
一种可能性是十六进制,即以 16 为基数。但是,使用大于 10 的基数会立即出现问题。具体来说,我们在 0 到 9 之后用完数字了——我们不能使用 10、11 或更大的数字,因为它们包含多个数字。因此,我们改用字母:A 代表 10,B 代表 11,C 代表 12,D 代表 13,E 代表 14,F 代表 15。因此,我们使用的数字是 0 到 F,而不是十进制中的 0 到 9,也不是二进制中的 0 和 1。
我们还必须重新审视每个位置的值。在十六进制中,每个位置代表 16 的幂。一个两位十六进制数有一个 16 位和一个 1 位。例如,D8 在 16 位处有 D,在 1 位处有 8。
16^1 16^0 <- hexadecimal places showing powers of 16 16 1 <- value of these places in decimal (base 10) D 8 <- our sample hexadecimal number
因此,十六进制数 D8 等于 十进制。请注意,任何两位十六进制数都可以表示与一个字节二进制数据相同的数量信息。(这是因为最大的两位十六进制数 ,与 8 位二进制相同。因此,它对我们来说更易于阅读或写入。
在处理数字时,有时使用哪种表示法并不清楚。例如,10 代表十(因此表示法为十进制)、二(表示法为二进制)、十六(十六进制),还是其他数字?通常,表示法从上下文中可以明显看出。但是,当不清楚时,我们会使用下标来澄清使用哪种表示法,例如 代表十进制, 代表二进制, 代表十六进制。
十六进制数可以具有我们已经看到的两位以上的十六进制数字。例如,考虑 ,它使用了以下 16 的幂。
16^7 16^6 16^5 16^4 16^3 16^2 16^1 16^0 F F 0 5 8 1 A 4
因此,在十进制中,它是:
十六进制并不经常出现,但它在某些地方使用,例如有时用于表示内存地址(您将在后面的章节中看到)或颜色。为什么在这些情况下它很有用?考虑一个 24 位 RGB 颜色,红色、绿色和蓝色分别为 8 位。由于 8 位需要 2 个十六进制数字,因此 24 位颜色需要 6 个十六进制数字,而不是 24 位。例如,FF0088表示一个 24 位颜色,红色分量为全色,绿色为无,蓝色为中级。
现在有更多类型的转换问题。
* Decimal to hexadecimal * Hexadecimal to decimal * Binary to hexadecimal * Hexadecimal to binary
以下是一些涉及最后两个问题的示例。
让我们将二进制数 00111100 转换为十六进制。为此,将其分成两个 4 位部分:0011 和 1100。现在将每个部分转换为十进制,得到 3 和 12。3 是一个十六进制数字,但 12 不是。相反,回想一下,C 是 12 的十六进制表示。因此,00111100 的十六进制表示为 3C。
除了从二进制转换为十进制(对于每个 4 位段),然后转换为十六进制数字之外,您还可以直接从二进制转换为十六进制。
十六进制数字及其十进制和二进制等效值:首先是 16 进制(十六进制),然后是 10 进制(十进制),然后是 2 进制(二进制)。
16 10 2 <- bases =========== 0 0 0000 1 1 0001 2 2 0010 3 3 0011 4 4 0100 5 5 0101 6 6 0110 7 7 0111 8 8 1000 9 9 1001 A 10 1010 B 11 1011 C 12 1100 D 13 1101 E 14 1110 F 15 1111
现在让我们将十六进制数 D6 转换为二进制。D 是 的十六进制表示,它在二进制中为 1101。二进制中的 6 为 0110。将这两个部分组合在一起得到 11010110。同样,我们可以使用上面的十六进制和二进制列跳过中间转换。
一段文本可以被视为符号流,可以表示/编码为一系列比特,从而生成文本的比特流。两种常见的编码方案是ASCII 码和Unicode。ASCII 码使用一个字节 (8 位) 来表示每个符号,可以表示多达 256 () 个不同的符号,其中包括英文字母表 (大小写) 和其他常用符号。Unicode 扩展了 ASCII 码,使用多个字节来表示更多符号。Unicode 可以表示任何书面语言中的任何符号,以及更多其他符号。
图像、音频和视频是其他类型的数据。计算机如何表示这些类型的数据非常有趣,但也复杂。例如,存在感知问题 (例如,人类能听到哪些类型的声音,以及这如何影响我们为了可靠地表示音乐而需要存储多少数字?),大小问题 (正如我们将在下面看到的,这些类型的数据会导致文件大小很大),标准问题 (例如,您可能听说过 JPEG 或 GIF 图像格式),以及其他问题。
我们无法深入介绍图像、音频和视频表示:细节过于复杂,而且可能非常复杂。例如,JPEG 图像可能依赖于一种称为离散余弦变换的先进数学技术。但是,值得考察关于图像、音频和视频文件的一些关键的高级要点。
- 计算机不仅可以表示基本的数字和文本数据,还可以表示诸如音乐、图像和视频等数据。
- 它们通过对数据进行数字化来实现这一点。在最低级别,数据仍然以比特的形式表示,但也有更高级别的表示结构。
- 有多种方法可以对这些数据进行编码,因此标准编码技术很有用。
- 音频、图像和视频文件可能很大,这在存储、处理和传输这些文件方面提出了挑战。为此,大多数编码技术使用了一些复杂的压缩类型。
感知图像的形成是由于光束物理地进入我们的眼睛并触发神经向我们的大脑发送信号。在计算中,图像通过一个点阵 (称为像素,代表“图像元素”) 来模拟,每个点都有特定的颜色。这是因为如果分辨率 (使用的点数) 足够高,我们的眼睛无法分辨原始图像和基于点的图像之间的区别。事实上,计算机屏幕本身就使用这样的像素点阵来显示图像和文本。
"我们银河系有史以来最大、最详细的照片已经公布。这张巨大的九十亿像素的图像捕捉到了银河系核心超过 8400 万颗恒星。它是由位于智利欧洲南方天文台帕拉纳尔天文台的可见光和红外巡天望远镜 (VISTA) 收集的数据创建的。该项目背后的团队表示,如果以报纸的分辨率打印,它将长 30 英尺,高 23 英尺,分辨率为 108,200 x 81,500 像素。"[5]
虽然这张银河系图像显然是一个极端的例子,但它说明了图像 (即使是更小的图像) 也可能占用大量的计算机空间。这里有一个更平凡的例子。假设您有一张宽度为 1500 像素,高度为 1000 像素的图像。每个像素以 24 位颜色存储。存储这张图像需要多少字节?
这个问题描述了一种直接但幼稚的存储图像的方法:对于每一行,对于每一列,存储该位置的 24 位颜色。答案是 个像素乘以 24 位/像素乘以 8 位/字节 = 450 万字节,约为 4.5 MB。
注意文件大小。如果您存储了许多照片或其他图像,您就会知道图像,尤其是图像集合,可能会占用相当大的存储空间。您可能也知道大多数图像不会占用 4.5 MB。而且您可能听说过一些图像存储格式,例如 JPEG 或 GIF。
为什么大多数图像大小是几十或几百 KB 而不是 MB?大多数图像不是以直接格式存储的,而是使用某种压缩技术。例如,假设您有一张夜间图像,图像的上半部分全部为黑色 ((0,0,0) 在 RGB 中)。与其在图像上半部分的像素数量上多次存储 (0,0,0),不如使用某种“速记”更有效。例如,与其在文件中包含数千个 0,不如用 (0,0,0) 加上一个数字来表示从图像开头 (如果从上到下逐行读取) 开始有多少像素具有颜色 (0,0,0)。
这将导致压缩图像:包含原始图像中所有或大部分信息的图像,但以更有效的方式表示。例如,如果原始图像会占用 4 MB,但更有效的版本占用 400 KB,那么压缩比就是 4 MB 到 400 KB,大约是 10:1。
复杂的压缩标准,例如 JPEG,使用各种技术来压缩图像。这些技术可能非常复杂。
图像可以压缩多少?它取决于许多因素。对于许多图像,例如,压缩比为 10:1 是可能的,但这取决于图像及其用途。例如,一个因素是图像的复杂程度。一个简单的图像 (例如,作为极端的例子,如果每个像素都是黑色的[6]),可以压缩很多。更丰富、更复杂的图像压缩得更少。但是,即使是复杂的图像通常也能压缩至少一些。
另一个考虑因素是压缩后的图像对原始图像的保真度。例如,许多用户会为了更小的文件大小而牺牲原始图像和压缩图像之间的一些微小差异,只要这些差异不容易察觉。一种不丢失任何图像信息的压缩方案称为无损方案。一种会丢失信息的方案称为有损方案。有损压缩比无损压缩效果更好,但会损失一些保真度。[7]
此外,图像的编码还包括其他元数据,例如图像的大小、编码标准以及创建日期和时间。
不难想象,视频可以编码为一系列图像帧,并使用比特同步编码的音频轨道。
假设您有一个 10 分钟的视频,分辨率为 256 x 256 像素,每个像素 24 位,每秒 30 帧。您使用的编码方式是为视频的每一帧的每个像素存储所有比特。总文件大小是多少?假设您有 500 千比特每秒的下载连接;下载文件需要多长时间?
这个问题突出了视频文件的一些挑战。注意文件大小问题的答案是 (256x256) 像素 24 位/像素 10 分钟 60 秒/分钟 30 帧每秒 = 大约 28 Gb(Gb 表示千兆位)。这大约是 28/8 = 3.5 千兆字节。以每秒 500 千位的速度下载,这将需要 28Gb/500 Kbps,大约 56,000 秒。这超过了 15 个小时,比许多人愿意等待的时间要长。如果每帧的像素数更大(例如,在全屏显示中)或视频长度更长,或者下载速度更慢,则时间只会增加。
因此,视频文件大小可能是一个问题。然而,下载一个十分钟的视频并不需要 15 个小时;就像图像文件一样,有一些方法可以减小文件大小和传输时间。例如,MPEG 等标准不仅利用图像压缩技术来减小单个帧的存储大小,而且还利用了一个帧中的场景通常与下一帧中的场景非常相似这一事实。网上有很多关于各种压缩技术和标准、存储介质等的信息。[8]
音频
[edit | edit source]乍一看,音频文件似乎不应该占用像视频那么多的空间。但是,如果你考虑音乐等复杂音频的复杂程度,你可能不会对音频文件也会很大感到惊讶。
声音本质上是振动,或是一组穿过空气的声波。人类可以听到频率在每秒 20 到 20,000 次循环之间的声波。[9] 为了避免某些不良的伪像,音频文件需要使用两倍于最高频率的采样率。因此,例如,对于 CD 音乐,通常以 44,100 赫兹或每秒 44,100 次进行采样。[10] 如果你想要立体声效果,你需要在两个通道上采样。对于每个样本,你想要使用足够多的位来存储振幅,以提供忠实的表示。CD 通常使用每个样本 16 位。因此,一分钟的音乐需要 44,100 个样本 16 位/样本 2 个通道 60 秒/分钟 8 位/1 字节 = 大约每分钟 10.5MB。这意味着一首 4 分钟的歌曲大约需要 40MB,一小时的音乐大约需要 630 MB,这大约是一张典型 CD 的存储容量。[11]
但是,请注意,如果你想通过 1Mbps 的连接下载一首 40 MB 的歌曲,则需要 40MB/1Mbps,大约需要 320 秒。这并不算很长,但如果可以更短就好了。因此,不出所料,有一些压缩方案可以显著缩短这个时间。例如,有一种 MPEG 音频压缩标准可以将 4 分钟的歌曲压缩到大约 4MB,这是一个很大的减少。[12]
表示的大小和限制
[edit | edit source]在上一节中,我们看到一页文本可能需要几千字节来存储。图像文件可能需要几万、几十万甚至更多字节。音乐文件可能需要数百万字节。电影文件可能需要数十亿字节。有些数据库包含数万亿或数千万亿字节的数据。
计算机科学对大量的字节有特殊的术语和表示法。以下是一个内存容量表,包括它们的 2 的幂和近似的美式英语单词。
1 kilobyte (KB) — bytes — thousand bytes 1 megabyte (MB) — bytes — million bytes 1 gigabyte (GB) — bytes — billion bytes 1 terabyte (TB) — bytes — trillion bytes 1 petabyte (PB) — bytes — quadrillion bytes 1 exabyte (EB) — bytes — quintillion bytes
仍然存在更高的数量级或更小的数量级。[13]
千字节、兆字节和其他大小在讨论文件大小、计算机内存大小等方面非常重要,因此你应该了解它们的术语和缩写。需要注意的是,文件大小通常以字节(或千字节、兆字节等)表示。但是,计算机科学中的一些数量通常以涉及位的术语表示。例如,下载速度通常以每秒位数表示。“Mbps”是兆位(不是兆字节)每秒的缩写。请注意,Mbps 中的 'b' 是小写的,而 MB(兆字节)中的 'b' 是大写的。
在计算机内存的上下文中,千字节、兆字节等的通常定义是 2 的幂。例如,一个千字节是 字节,而不是一千字节。然而,在其他一些情况下,千字节被定义为正好是一千字节。这显然会让人困惑。本书中,这种差异通常并不重要。也就是说,在我们大多数情况下,近似值已经足够接近。因此,例如,如果我们进行计算并发现一个文件需要 6,536 字节,那么你可以说这大约是 6.5 KB,除非问题说明中另有说明。[14]
所有表示方法在多种方面都存在局限性。首先,我们可以表示的不同事物数量是有限的,因为我们使用的符号组合的数量总是受到可用物理空间的限制。例如,如果您要通过在纸上写下来来表示一个十进制数,那么纸张的大小和字体的尺寸限制了您可以写下的位数。同样,在计算机中,可以物理存储的位数也是有限的。使用三个二进制位,我们可以生成 个不同的表示/模式,即,它们通常分别代表 0 到 7。请记住,表示方法没有内在含义。因此,三个位可以可能代表七个不同的东西。使用 n 个位,我们可以代表 个不同的东西,因为每个位可以是 1 或 0,而 是我们可以得到的总组合数,它限制了我们可以表示的信息量。
另一种限制是由于表示方法的性质造成的。例如,三分之一永远无法通过带有小数部分的十进制格式精确表示,因为小数点后将有无穷多个三。同样,三分之一也不能以二进制格式精确表示。换句话说,不可能将三分之一表示为二的幂的有限列表的总和。但是,在三进制记数系统中,三分之一可以精确地表示为:,因为小数点后的 1 代表三的幂:。
- ↑ 模拟 在 维基词典 上。
- ↑ 实际上,这比这更复杂,因为一些设备(包括一些数字广播)混合了数字和模拟。例如,数字广播可能以数字形式开始,即作为数字流,然后转换为无线电波并以无线电波的形式传输,然后接收并转换回数字形式。严格来说,信号是调制和解调的。如果您在计算机上有一个调制解调器(调制器-解调器),它执行类似的功能。
- ↑ 实际上,我们不仅需要数据,还需要一种方法来表示计算机内的算法。计算机如何存储算法指令将在另一章中讨论。
- ↑ 当然,0 或 1 的表示方式因设备而异。例如,在计算机中,区分 0 和 1 的常用方法是通过电气特性,例如使用不同的电压电平。在光纤电缆中,光脉冲的存在或不存在可以区分 0 和 1。光存储设备可以通过光盘表面位置上反射率影响的小“凹坑”的存在或不存在来区分 0 和 1。
- ↑ [1]
- ↑ 您可能见过现代艺术绘画,其中整个作品都是单色。
- ↑ 例如,参见 [2],了解压缩率和图像保真度之间相互作用的示例。
- ↑ 例如,参见 [3] 以及那里的链接。
- ↑ 这只是一个粗略的估计,因为存在很多个体差异,以及影响此范围的其他因素。
- ↑ Hz 或 赫兹,是频率的测量单位。它出现在计算机科学、计算机工程以及相关领域(如电气工程)的许多地方。例如,计算机显示器可能具有 60Hz 的刷新率,这意味着它每秒重新绘制 60 次。它也用于许多其他领域。例如,在大多数现代的音乐会音乐中,中音 C 上的 A 被认为是 440 Hz。
- ↑ 例如,参见 [4],以了解更多关于 CD 工作原理的信息。一般来说,有很多关于音频文件、格式、存储介质等的网站。
- ↑ 请记住,还存在 MPEG 视频压缩标准。MPEG 实际上有一套标准:参见维基百科上的 运动图像专家组。
- ↑ 例如,参见 二进制前缀。
- ↑ 对于较小的字节数,“圆”数(如一百万)和 10 的幂之间的差异并不像对于较大的字节数那样明显。一个千字节是 个字节,只比一千多 2.4%。一个兆字节是 个字节,大约比一百万多 4.9%。一个吉字节大约比十亿多 7.4% 个字节,一个太字节大约比一万亿多 10.0% 个字节。在我们做的大多数文件大小问题中,我们将对近似大小感兴趣,并且相差 2%、5% 或 10% 并不重要。当然,存在现实世界的应用程序,其中它很重要,因此在做文件大小问题时请记住我们正在进行近似计算,而不是精确计算。