计算机如何用二进制数存储数据
电影中的编程和黑客攻击通常涉及在屏幕上流动的 1 和 0 流。 这看起来神秘而令人印象深刻,但这些 1 和 0 究竟意味着什么? 您可能知道二进制数(仅使用两位数,零和一编写的数字)与计算机有关,但不知道为什么。
答案是经济学:二进制是最简单的数字系统,它可以用相对便宜的计算机硬件组件来实现。 二进制,也称为 base-2 数字系统,可以表示我们更熟悉的 base-10 十进制数字系统可以表示的所有相同数字。 十进制有十位数字,从 0 到 9。下表显示了十进制和二进制的前 24 个数字:
十进制二进制十进制二进制001211001113110121014111031115111141001610000510117100016110181001071119100118100020101009100121101011010112111011121101111
将数字系统想象成一个机械里程表:当您到达最后一位时,它会重置回零,同时递增下一位。 十进制最后一位是9,二进制最后一位是1。9后面的十进制数是10,999后面的十进制数是1000。同理,1后面的二进制数是10,111后面的二进制数是1000。虽然二进制中的“10”与十进制中的“十”并不表示相同的数量,而是两个。 而二进制的“1000”与十进制的“一千”所代表的数量不同,而是八。 您可以在 https://inventwithpython.com/odometer 查看交互式二进制和十进制里程表
用计算机硬件表示二进制数比十进制数简单,因为只有两种状态可以表示。 例如,旋转磁盘硬盘驱动器具有可以被磁化或不被磁化的微观点。 蓝光光盘和 DVD 在光盘表面刻有光滑的“平台”和锯齿状的“凹坑”,它们分别会或不会反射光盘播放器的激光。 电路可以有电流流过它们,也可以没有电流。 即使是 20 世纪中叶计算机的纸质打孔卡上的空格也有打孔或没有打孔。 这些不同的硬件标准都有表示两种不同状态的方式。 另一方面,制造足够灵敏以可靠准确地检测十种不同电压电平之间差异的高质量电子元件将是昂贵的。 使用简单的组件更经济,两个二进制状态是尽可能简单。
这些二进制数字简称为比特。 一位可以表示两个数字,八位(或一个字节)可以表示 2^8 或 256 个数字。 十进制范围为 0 到 255,二进制范围为 0 到 11111111。 这类似于一个十进制数可以表示十个数字(0 到 9),八位十进制数可以表示 10^8 或一亿个数。 您计算机上的文件以占用的字节数来衡量:
- 一千字节是 2^10 或 1,024 字节。 一兆字节是 2^20 或 1,048,576 字节。 1 GB 是 2^30 或 1,073,741,824 字节。
莎士比亚的《罗密欧与朱丽叶》全文约 135 KB。 一张高分辨率照片大约有 2 到 5 兆字节。 一部两小时的电影根据图片质量的不同,大小可能在 1 到 50 GB 之间。 硬盘驱动器制造商和互联网服务提供商通常会使用千字节、兆字节和千兆字节来表示一千、一百万或十亿,因为这使他们能够过分夸大他们提供的容量。 公司可以这样公然谎报数字的原因是因为世界就是这样运作的。
一旦有了表示二进制数的方法,就可以用任何数字系统表示数字。 您无需了解从 base-2 转换为 base-10 以及反之亦然的数学原理,即可编写自动化无聊内容的 Python 脚本。 Python 具有为您执行此数学运算的函数:调用 bin(42)
返回字符串 '0b101010'
. 这 '0b'
prefix 是将数字标记为二进制的约定,而不是十进制中的“十万一千十”。 与此同时,呼唤 int('101010', 2)
将二进制转换为十进制并返回整数 42
. 这 2
论据告诉 int()
发挥作用 '101010'
是一个以 2 为底的二进制数。
二进制的1和0不仅可以表示任何整数,也可以表示任何形式的数据。 通过为每个字母、标点符号或符号分配一个唯一的数字,文本可以作为二进制数字存储在计算机上。 一个早期的此类方案是 ASCII,即美国信息交换符号代码。 在 ASCII 中,大写字母“A”由数字 65(或二进制 1000001)表示,“?” 问号由数字 63 表示,数字 7 由数字 55 表示。字符串 'Hello'
存储为数字 72、101、108、108 和 111。当一个接一个组合时,它显示为二进制流:10010001100101110110011011001101111。
哇! 就像那些黑客电影一样!
但是,如果不知道每个数字中有多少位数字,这些就没有意义。 代表 'Hello'
在十进制中,如 72101108108111 令人困惑,因为您不知道第一个字母是由 7、72 还是 721 表示。我们可以通过始终为每个字母使用三位数字并在需要的地方添加前导零来解决此问题:72 变为 072。 072101108108111的十五位数字可以平均分成五组,每组三位数字代表五个字母。 同样可以用二进制来完成,其中一个字节(或八位)代表每个字母。 随着前导零, 'Hello'
变成0100100001100101011011000110110001101111,如图:
用二进制编写大数字可能很乏味,因此程序员通常以 base-16 或十六进制查看二进制信息。 十六进制(或简单的,十六进制)的数字范围从0到9,然后继续前六个字母A到F如下表:
DemimalHexAdeCimalbinary DecimalHexAdeCimalBinary00012C11001111111111221014E1110331115F11111111111410016101005555111111111111111011011011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111转
单个十六进制数字A代表数字十,B代表十一,依此类推直到F代表15。在此之后,我们添加另一个十六进制数字:十六进制数字10代表十进制16。Python的 hex()
和 int()
函数在十进制和十六进制之间转换。 在交互式 shell 中输入以下内容:
>>> hex(42) # Convert decimal to hex '0x2a' >>> int('0x2a', 16) # Convert hex to decimal 42 >>> int('0x2A', 16) # Convert hex to decimal 42 >>> int('2A', 16) # Convert hex to decimal 42
这 hex()
函数返回字符串 '0x'
前缀以将其标记为十六进制数。 这 16
论据告诉 int()
发挥作用 '2a'
以 base-16 十六进制编写。
这 'Hello'
字符串可以用 40 个二进制数字显示,0100100001100101011011000110110001101111,或者更紧凑地用 10 个十六进制数字显示,48656c6c6f。 这种形式更便于程序员阅读,称为十六进制编辑器的软件可以以这种方式显示文件的二进制数据。
ASCII 是在因特网使国际通信变得司空见惯之前开发的。 它没有为汉字保留的数字。 它不仅是英语的编码,也是美式英语的编码:“$”美元符号的数字是 36,但英镑符号没有数字。 Unicode 标准解决了这些问题。 具体来说,Unicode 标准的 UTF-8 编码使用一到四个字节来表示任何可能的字符。 UTF-8 还向后兼容 ASCII:65 是 ASCII 和 UTF-8 中的大写字母 A。
蟒蛇的 ord()
函数采用单字符字符串并返回其分配的 Unicode 代码点的整数。 蟒蛇的 chr()
函数做相反的事情,取一个整数并返回该数字分配的 Unicode 字符的单字符字符串。 这样,所有文本都可以表示为数字,所有数字都可以二进制形式存储在计算机硬件上。
工程师需要发明一种方法将每种形式的数据编码为数字。 照片和图像被分解成称为像素的彩色方块的二维网格。 每个像素可以使用三个字节来表示其颜色包含多少红色、绿色和蓝色。 使用 Python 自动化无聊的东西的第 19 章更详细地介绍了图像数据。 但举个简短的例子,数字 255、0 和 255 可以表示具有最大红色和蓝色但没有绿色的像素,从而产生紫色像素。
声音由到达我们耳朵的压缩空气波组成,我们的大脑将其解释为听觉。 我们可以绘制这些波随时间变化的强度和频率。 然后可以将此图形的数字转换为二进制数并存储在计算机中,计算机稍后可以控制扬声器重放声音。 这是一种简化,但这是二进制数在 MP3 等音频文件中的存储方式。
多个图像的数据与音频数据结合以存储视频。 所有形式的信息都可以编码成数字,转换成二进制数,然后存储在计算机硬件上。 当然,它的意义远不止于此,但这就是 1 和 0 在我们的信息时代代表各种数据的方式。