try ai
科普
编辑
分享
反馈
  • 八进制 (Octal) 数制

八进制 (Octal) 数制

SciencePedia玻尔百科
核心要点
  • 八进制(octal)系统只使用0到7这几个数字,计数在达到7后“进位”到10。
  • 其主要价值源于它与二进制的直接关系(8=238 = 2^38=23),使得每个八进制数字能精确地代表三位二进制数。
  • 八进制是二进制的一种紧凑、人类可读的简写形式,在Unix/Linux文件权限和遗留计算机系统中得到了著名应用。
  • 在八进制、十进制和十六进制等数制之间进行转换是一个系统化的过程,可以使用诸如连续除法或以二进制为中介的方法。

引言

我们的世界由十进制主导。我们使用十进制系统进行计数,很可能是因为我们有十根手指。但如果我们的计数系统是基于八,情况会怎样呢?这个问题引出了八进制(octal)或称基数为8的数制,这是一个理解计算机内部工作原理的基础概念。虽然我们精通十进制,但计算机以二进制运行,这在两者之间造成了需要弥合的沟通鸿沟。本文旨在揭开八进制系统的神秘面纱,展示它如何作为人类指令与机器代码之间优雅而高效的翻译器。在接下来的章节中,您将首先在“原理与机制”部分探索八进制算术和转换的基本规则。然后,在“应用与跨学科联系”部分,您将发现它在硬件设计、编程以及我们日常使用的文件系统中的强大用途。

原理与机制

你有没有停下来想过数字十?它看起来如此自然,如此基础。我们有十个数字(0到9),当我们数过九时,我们只是简单地进位:我们在左边的下一位放上‘1’,然后从‘0’重新开始。我们有个位、十位、百位,依此类推。但为什么是十呢?最可能的原因就在你的手臂末端。我们有十根手指。我们整个计数系统都建立在这个生物学上的偶然之上。

如果我们是卡通人物,每只手只有四根手指,总共八根,那我们会如何计数呢?这不仅仅是一个异想天开的问题;它是解开所有不同数制世界的钥匙,包括​​八进制​​(​​octal​​),即​​基数为8​​的系统。

一个有八根手指的世界

在一个基数为8的世界里,我们只有八个数字可用:0、1、2、3、4、5、6和7。数字‘8’和‘9’根本不存在。当你计数时,你会像平常一样进行——直到你数到七。七之后是什么?由于你用完了所有数字,你必须做我们在九之后所做的事情:进位。7后面的数字不是8,而是10。这看起来像我们的“十”,但在八进制世界里,它意味着“一组八,零个一”。

让我们看看实际操作。假设一个数字计数器一次向前跳一步,但它是用八进制思考的。如果它从 (36)8(36)_8(36)8​ 开始,下一个数字是通过给最后一位加一得到的:6+1=76+1=76+1=7。所以下一个状态是 (37)8(37)_8(37)8​。但那之后的一步是什么呢?我们需要计算 (37)8+(1)8(37)_8 + (1)_8(37)8​+(1)8​。当我们将1加到7时,我们得到8,这是不允许的!在基数8中,‘八’这个计数被表示为 (10)8(10)_8(10)8​。所以,‘7’变成‘0’,我们向下一位​​进位​​‘1’,就像你在计算 19+119+119+1 时进位一样。八位(即 818^181 位)上的数字是3,现在我们加上进位:3+1=43+1=43+1=4。所以,(37)8(37)_8(37)8​ 后面的数字是 (40)8(40)_8(40)8​。从 (36)8(36)_8(36)8​ 到 (42)8(42)_8(42)8​ 的完整计数序列将是 (36)8,(37)8,(40)8,(41)8,(42)8(36)_8, (37)_8, (40)_8, (41)_8, (42)_8(36)8​,(37)8​,(40)8​,(41)8​,(42)8​。你看,计数的基本机制是相同的,只是“进位”点改变了。

这种进位机制可以产生美丽的级联效应。(377)8+(1)8(377)_8 + (1)_8(377)8​+(1)8​ 是多少?

  • 最右边的数字:7+17+17+1 变成 0,进位 1。
  • 中间的数字:7+17+17+1(来自进位)变成 0,进位 1。
  • 最左边的数字:3+13+13+1(来自进位)变成 4。 结果是 (400)8(400)_8(400)8​。这完全类似于在我们熟悉的十进制系统中 399+1399+1399+1 如何变成 400400400。同样的逻辑也适用于减法,但需要借位。(200)8(200)_8(200)8​ 前面的数字不是 (199)8(199)_8(199)8​(数字‘9’是非法的!),而是 (177)8(177)_8(177)8​。要找到这个数,我们必须从最左边的数字跨过零来借位,就像我们计算 200−1=199200-1=199200−1=199 一样。

在不同世界间转换

理解如何在基数8中计数是一回事,但这些数字在我们的十进制世界里意味着什么?转换的关键在于​​位值记数法​​(positional notation)的概念。在十进制中,数字 652652652 是 6×102+5×101+2×1006 \times 10^2 + 5 \times 10^1 + 2 \times 10^06×102+5×101+2×100 的简写。每个数字的位置赋予了它基于10的次幂的权重或值。

八进制系统的工作方式完全相同,但权重是8的次幂。要将一个像 (62)8(62)_8(62)8​ 这样的八进制数转换为我们的十进制系统,我们只需写出它的含义: (62)8=6×81+2×80=6×8+2×1=48+2=50(62)_8 = 6 \times 8^1 + 2 \times 8^0 = 6 \times 8 + 2 \times 1 = 48 + 2 = 50(62)8​=6×81+2×80=6×8+2×1=48+2=50 所以,八进制的“六十二”与十进制的“五十”是相同的数量。这个原理优美地扩展到了带小数部分的数字。基数点右边的位置代表基数的负次幂。对于 (17.4)8(17.4)_8(17.4)8​,转换如下: (17.4)8=1×81+7×80+4×8−1=8+7+48=15.5(17.4)_8 = 1 \times 8^1 + 7 \times 8^0 + 4 \times 8^{-1} = 8 + 7 + \frac{4}{8} = 15.5(17.4)8​=1×81+7×80+4×8−1=8+7+84​=15.5 结构是完全一致的,从基数的正次幂无缝地流向负次幂。

反过来——从十进制到八进制——则需要一种不同的思维方式。这就像换零钱。要将十进制数99转换为八进制,我们问:“我们能凑出多少组8?”我们可以使用连续除法算法。

  1. 将 99 除以 8:99÷8=1299 \div 8 = 1299÷8=12,余数为 ​​3​​。这个余数是我们的最后一位数字(个位)。
  2. 取商 12,再除以 8:12÷8=112 \div 8 = 112÷8=1,余数为 ​​4​​。这是我们的下一位数字(八位)。
  3. 取新的商 1,再除以 8:1÷8=01 \div 8 = 01÷8=0,余数为 ​​1​​。这是我们的第一位数字(六十四位)。 从下往上读取余数,我们得到 (143)8(143)_8(143)8​。所以,(99)10=(143)8(99)_{10} = (143)_8(99)10​=(143)8​。对于小数部分,我们使用重复乘法。要转换0.125,我们乘以8。0.125×8=1.00.125 \times 8 = 1.00.125×8=1.0。整数部分1,是我们的第一个八进制小数位。由于其余部分为零,我们完成了。因此,(72.125)10(72.125)_{10}(72.125)10​ 变成 (110.1)8(110.1)_8(110.1)8​。

八进制与二进制之间的秘密握手

此时,你可能会认为这只是一个有趣的智力练习,但它有什么用呢?为什么会有人费心去用基数8?答案不在于它与基数10的关系,而在于它与​​二进制​​(即基数2),所有计算机的母语,之间深刻的联系。

计算机以​​比特​​(bits)——由1和0代表的简单的开/关状态——来思考。一长串二进制数,如 110101011,对于机器来说完全清晰,但对于人类程序员来说,阅读或转录却是一场噩梦。这就是八进制发挥作用的地方。其魔力在于一个简单的数学事实:8=238 = 2^38=23。

这意味着每一个八进制数字都精确对应一组三位二进制数。这是一种一一对应的映射,是两个系统之间的秘密握手。

  • (0)8=(000)2(0)_8 = (000)_2(0)8​=(000)2​
  • (1)8=(001)2(1)_8 = (001)_2(1)8​=(001)2​
  • (2)8=(010)2(2)_8 = (010)_2(2)8​=(010)2​
  • ...
  • (7)8=(111)2(7)_8 = (111)_2(7)8​=(111)2​

要将一个长的二进制数转换为八进制,你不需要复杂的除法或乘法。你只需从右到左将比特按三位一组进行分组,然后翻译每一组。对于二进制字符串 (110101011)2(110101011)_2(110101011)2​: 110⏟6101⏟5011⏟3\underbrace{110}_{6} \quad \underbrace{101}_{5} \quad \underbrace{011}_{3}6110​​5101​​3011​​ 该二进制字符串变成了紧凑且可读的八进制数 (653)8(653)_8(653)8​。这种转换只是一个简单的查找。反向转换同样简单。要找到 (617)8(617)_8(617)8​ 的9位二进制字符串,我们只需展开每个数字: 6⏟1101⏟0017⏟111\underbrace{6}_{110} \quad \underbrace{1}_{001} \quad \underbrace{7}_{111}1106​​0011​​1117​​ 将这些连接起来得到 (110001111)2(110001111)_2(110001111)2​。这就是为什么像PDP-8这样的早期计算机系统严重依赖八进制。它充当了机器真实二进制语言的一种人类友好型简写。

计算机减法的巧妙技巧

这些数制的实用性甚至延伸得更深,直达计算机处理器的设计核心。机器如何处理减法和负数?一种暴力的方法是为加法和减法构建独立的电路。但自然和优秀的工程设计都是经济的。更优雅的做法是让一个电路同时完成这两种运算。这是通过一种名为​​补码运算​​的巧妙技巧实现的。

其思想是将每个减法问题,如 A−BA - BA−B,转化为一个加法问题,A+(负 B)A + (\text{负 } B)A+(负 B)。“负B”由其补码表示。在一个3位有符号八进制系统中,我们可以定义一个约定:如果第一位数字是0-3,则该数为正;如果是4-7,则为负。要执行减法 (142)8−(371)8(142)_8 - (371)_8(142)8​−(371)8​,我们首先找到 (371)8(371)_8(371)8​ 的​​8的补码​​。一个简单的方法是找到7的补码(用7减去每个数字)然后加1。

  • (371)8(371)_8(371)8​ 的7的补码是 (7−3)(7−7)(7−1)=(406)8(7-3)(7-7)(7-1) = (406)_8(7−3)(7−7)(7−1)=(406)8​。
  • 8的补码是 (406)8+(1)8=(407)8(406)_8 + (1)_8 = (407)_8(406)8​+(1)8​=(407)8​。

现在,我们的减法变成了加法:(142)8+(407)8(142)_8 + (407)_8(142)8​+(407)8​。执行标准的八进制加法得到 (551)8(551)_8(551)8​。因为结果的最高有效位(5)落在负数范围(4-7)内,这就是我们的最终答案,已经是以其负数表示形式。我们成功地仅用加法机制完成了减法。这不仅仅是一个数学上的奇趣;它是一个基本原理,使得我们手机、笔记本电脑和服务器中的处理器变得高效且可能。

从简单的掰指头数数,我们可以构建一个具有不同规则的世界,看到如何在它与我们的世界之间进行转换,发现它与机器语言之间隐藏的、优雅的联系,甚至理解让那些机器工作的巧妙技巧。八进制系统不仅仅是另一个数基;它是一扇窗,让我们得以窥见支撑我们数字现实的美丽、统一的数字与逻辑结构。

应用与跨学科联系

在了解了八进制系统的基本原理之后,我们可能会将其视为一种纯粹的数学奇趣,是熟悉的十进制与计算机原生二进制之间的垫脚石。但这就像是看着一把制作精美的钥匙,却从未意识到它能打开各种复杂的锁。基数8的真正优雅之处不仅在于其结构,更在于其与数字世界深刻而实际的关系。它的力量在于它作为完美翻译器的角色,一座连接人类思维与机器二进制核心的紧凑而直观的桥梁。

硬件的流利语言

在其核心,计算机以一连串的1和0交流——这种语言对电子设备来说是精确的,但对人类来说却既笨拙又容易出错。想象一下,试图通过拨动一长排开关来配置一件硬件。记住像 111010 这样的序列远比记住两位数 72 要困难得多。这正是八进制首次展现其简洁才华的地方。因为 8=238 = 2^38=23,每一个八进制数字都精确地对应一组三位二进制数。这不是巧合;这正是其效用的根源。

想象一位工程师正在使用一个老旧的电机控制器。为方便人类使用而编写的手册指定了一个配置代码,如 (72)8(72)_8(72)8​。对机器而言,这是一组六个物理开关。工程师的任务是一个简单而优雅的转换:7 变成 111(三个开关拨到‘开’),2 变成 010(接下来三个开关的中间一个拨到‘开’)。完整的设置是 111010。八进制代码不是一个近似值;它是二进制现实的直接、紧凑的表示。

这一原理深深地延伸到计算机的体系结构中。早期的计算机设计师和程序员广泛使用八进制来表示内存地址和指令代码。当调试一个地址为 (275)8(275)_8(275)8​ 的老式微控制器时,程序员可以立即想象出底层的比特模式,即使需要将其转换为像 189189189 这样的十进制值以便与现代工具接口。这种从单个八进制数字到三位比特的直接映射,在设计和编程那些需要位级控制的系统中被证明是无价的。

当硬件本身就是以2的幂来构建时,这种关系的美感最为引人注目。考虑一个8-1多路复用器,这是一个选择八个输入之一的数字开关。它如何知道选择哪个输入呢?它使用三条“选择线”,而这些线上的3位二进制数决定了选择。多么完美的匹配!一个从0到7的八进制数字就可以指定八条线中的哪一条被选中。一个 (6)8(6)_8(6)8​ 的命令被电路立即翻译成二进制信号 (110)2(110)_2(110)2​,第六个输入就被选中了。数制反映了硬件设计。同样,一个9位数模转换器的最大值是一串九个1,即 (111111111)2(111111111)_2(111111111)2​。在八进制中,这只是 (777)8(777)_8(777)8​,一个清晰且易于记忆的系统极限表示。

有时,这种转换需要应对处理器设计的特定怪癖。一位工程师可能会发现一个处理器指令被记录为 (53)8(53)_8(53)8​。这可以翻译成6位二进制字符串 (101011)2(101011)_2(101011)2​。然而,如果硬件出于其自身特殊的原因,以相反的顺序读取这些比特,工程师必须知道要将其翻转为 (110101)2(110101)_2(110101)2​ 才能理解机器实际将执行什么。在所有这些情况下,八进制都充当了驱动机器的原始二进制数据的清晰、简洁、面向人类的语言。

通用翻译器:作为通用语的二进制

虽然八进制是基于三位比特的分组,但现代计算通常偏爱基于四位比特分组的十六进制(基数16)(16=2416 = 2^416=24)。这是否使八进制过时了?完全没有。相反,它凸显了一个更深层次的原则:二进制是通用的通用语(lingua franca)。在八进制和十六进制之间进行翻译,就是见证这一原则的实际应用。

你不能直接将一个八进制数字转换为一个十六进制数字。相反,你需要通过它们共同的基础走一条‘风景路线’。要将像 (52)8(52)_8(52)8​ 这样的八进制数转换为十六进制,你首先将其展开为二进制形式:5 变成 101,2 变成 010,得到 (101010)2(101010)_2(101010)2​。现在,你只需将这些相同的比特重新分组为四位一组,从右边开始:10 和 1010。用前导零将第一组补全为 0010。这些组可以直接转换为十六进制:0010 是 2,1010 是 A。所以,(52)8(52)_8(52)8​ 是 (2A)16(2A)_{16}(2A)16​。同样的过程也适用于反向转换,将像 (BEEF)16(BEEF)_{16}(BEEF)16​ 这样的值转换为其八进制等价物 (137357)8(137357)_8(137357)8​,方法是将其转换为一个长的二进制字符串,然后重新按三位分组。这不是一个笨拙的两步过程;它优美地展示了这些数基只是我们观察相同底层二进制数据的不同窗口。

超越数字:编码结构与意义

八进制系统最深远的应用,或许是当其数字不仅仅代表一个数量,而是一系列属性的集合时。与一个八进制数字对应的三位比特中的每一位都可以被看作一个独立的开/关标志。这将八进制从一个简单的简写提升为一个用于编码结构化信息的强大系统。

这方面最著名且经久不衰的例子是类Unix操作系统(如Linux和macOS)中的文件权限系统。当你看到权限以八进制数如 (751)8(751)_8(751)8​ 给出时,你看到的不是一个单一的数量。你看到的是三组独立的规则。第一个数字 7 代表文件所有者;第二个 5 代表指定的用户组;第三个 1 代表其他所有人。

这个意义从何而来?每个数字是三个权限值的总和:读(值为4,或 1002100_21002​)、写(值为2,或 0102010_20102​)和执行(值为1,或 0012001_20012​)。

  • 7 是 4+2+14+2+14+2+1,意味着读、写和执行权限都被授予((111)2(111)_2(111)2​)。
  • 5 是 4+14+14+1,意味着读和执行,但没有写权限((101)2(101)_2(101)2​)。
  • 1 意味着只有执行权限((001)2(001)_2(001)2​)。

这是一个极其优雅的设计。通过一个数字,管理员可以表达三个独立的‘是/否’选择。八进制系统为这种三比特命令结构提供了完美的词汇。

这种使用数制来审视结构化数据的思想在更复杂的领域中找到了应用。想象一种自定义的9位浮点数格式,这是所有现代科学计算中使用的格式的简化版。一个存储为 (652)8(652)_8(652)8​ 的值,对机器来说是二进制字符串 110 101 010。利用我们对该格式的知识,我们可以解析它:第一位(1)是符号位,接下来的三位(101)编码指数,最后五位(01010)构成尾数。这使我们能够解构这个数字并找到它的十进制值,在本例中是 −5.25-5.25−5.25。在这里,八进制就像一个放大镜,帮助我们在看似单一的比特串中看到不同的字段。

此外,这种结构化视图使我们能够构建更稳健的系统。想象一下将数据作为一系列八进制数字传输。我们如何确保数据在传输过程中没有损坏?我们可以增加一个错误校验层。对于每个八进制数字(3位),我们可以添加第四个“奇偶校验”位,设置该位以确保4位组中‘1’的总数为偶数。如果在传输过程中有一个比特被意外翻转,这个奇偶校验将失败,立即标记出损坏的数字。一个接收数据流的系统可以验证每个传入的4位块的奇偶性,以确定原始八进制数字(比如 4、2、7 或 1)中哪一个是损坏传输的一部分。

从拨动开关的切实手感到文件权限和纠错码的抽象逻辑,八进制系统远不止是一个历史注脚。它证明了找到正确表示形式的力量。它与二进制之间简单而优美的 232^323 关系使其能够充当一座桥梁、一种简写和一个透镜,将人类的直觉更近一步地引向数字宇宙的基本逻辑。