您可能知道,计算机上的所有内容都以比特串(二进制数字;您可以将其视为许多小开关)的形式存储。在这里,我们将解释这些比特如何用于表示您的计算机正在处理的字母和数字。
在我们深入探讨之前,您需要了解您计算机的字长。字长是计算机移动信息单元的首选大小;从技术上讲,它是处理器寄存器的宽度,寄存器是处理器用于进行算术和逻辑计算的保存区域。当人们谈论计算机的位大小时(称其为“32 位”或“64 位”计算机),他们指的就是这个。
现在大多数计算机的字长为 64 位。在不久的过去(2000 年代初期),许多 PC 的字长为 32 位。 1980 年代的老式 286 机器的字长为 16 位。老式大型机通常具有 36 位的字长。
计算机将您的内存视为一系列字,从零开始编号,一直到某个很大的值,该值取决于您的内存大小。该值受您的字长限制,这就是为什么像 286 这样的旧机器上的程序必须经历痛苦的扭曲才能寻址大量内存。我不会在这里描述它们;它们仍然给老程序员带来噩梦。
整数表示为字或字对,具体取决于处理器的字长。一个 64 位机器字是最常见的整数表示形式。
整数算术接近但不完全是数学上的二进制。最低位是 1,下一个是 2,然后是 4,依此类推,就像纯二进制一样。但是有符号数以补码表示法表示。最高位是符号位,它使该量为负数,并且每个负数都可以通过反转所有位并加一从相应的正值获得。这就是为什么 64 位机器上的整数范围为 -263 到 263 - 1。第 64 位用于符号; 0 表示正数或零,1 表示负数。
某些计算机语言允许您访问无符号算术,它是纯粹的二进制,仅包含零和正数。
大多数处理器和一些语言可以进行浮点数运算(此功能内置于所有最新的处理器芯片中)。浮点数为您提供比整数更广泛的值范围,并允许您表示分数。完成此操作的方式各不相同,并且过于复杂,无法在此处详细讨论,但总体思路很像所谓的“科学计数法”,例如,可以写成 1.234 * 1023;数字的编码分为尾数 (1.234) 和指数部分 (23),用于十的幂乘数(这意味着乘出的数字将有 20 个零,即 23 减去三个小数位)。
字符通常以七位字符串的形式表示,编码称为 ASCII(美国信息交换标准代码)。在现代机器上,128 个 ASCII 字符中的每一个都是八位字节或 8 位字节的低七位;八位字节被打包到内存字中,因此(例如)一个六字符的字符串仅占用一个 64 位内存字。对于 ASCII 代码表,请在 Unix 提示符下键入“man 7 ascii”。
前面的段落在两个方面具有误导性。次要的一点是,“八位字节”一词在形式上是正确的,但实际上很少使用;大多数人将八位字节称为字节,并期望字节为八位长。严格来说,“字节”一词更通用;例如,过去曾有 36 位机器,字节为 9 位(尽管可能永远不会再有了)。
主要的一点是,并非全世界都使用 ASCII。事实上,世界上很多地方都不能使用——ASCII 虽然对于美式英语来说很好,但缺少其他语言用户需要的许多重音和其他特殊字符。即使是英式英语也难以处理缺少英镑货币符号的问题。
已经有几种尝试来解决这个问题。所有这些都使用了 ASCII 没有的额外高位,使其成为 256 个字符集中的低半部分。其中最广泛使用的是所谓的“Latin-1”字符集(更正式的名称是 ISO 8859-1)。这是 Linux、旧版本 HTML 和 X 的默认字符集。 Microsoft Windows 使用 Latin-1 的变体版本,该版本在适当的 Latin-1 为历史原因未分配的位置添加了一堆字符,例如左右双引号(有关此问题引起的麻烦的尖锐说明,请参阅 demoroniser 页面)。
Latin-1 处理西欧语言,包括英语、法语、德语、西班牙语、意大利语、荷兰语、挪威语、瑞典语、丹麦语和冰岛语。然而,这仍然不够好,因此出现了一系列 Latin-2 到 -9 字符集,用于处理希腊语、阿拉伯语、希伯来语、世界语和塞尔维亚-克罗地亚语等内容。有关详细信息,请参阅 ISO 字母汤 页面。
最终的解决方案是一个名为 Unicode 的庞大标准(及其相同的孪生兄弟 ISO/IEC 10646-1:1993)。 Unicode 在其最低的 256 个槽位中与 Latin-1 相同。在 16 位空间中的这些之上,它包括希腊语、西里尔语、亚美尼亚语、希伯来语、阿拉伯语、梵文、孟加拉语、古木基语、古吉拉特语、奥里亚语、泰米尔语、泰卢固语、卡纳达语、马拉雅拉姆语、泰语、老挝语、格鲁吉亚语、藏语、日语假名、完整的现代韩语谚文以及统一的汉字/日语/韩语 (CJK) 象形文字集。有关详细信息,请参阅 Unicode 主页。 XML 和 XHTML 使用此字符集。
最新版本的 Linux 使用 Unicode 的一种编码,称为 UTF-8。在 UTF 中,字符 0-127 是 ASCII。字符 128-255 仅在 2 到 4 个字节的序列中使用,这些序列标识非 ASCII 字符。