【问题标题】:Where did the octal/hex notations come from? [closed]八进制/十六进制符号从何而来? [关闭]
【发布时间】:2010-12-22 13:41:19
【问题描述】:

这么久以来,我从未想过要问这个问题;我知道这来自 c++,但它背后的原因是什么:

  • 指定十进制数 通常会
  • 用前导 0 指定八进制数
  • 用前导 0x 指定十六进制数

为什么是 0?为什么是 0x? base-32 有自然的进展吗?

【问题讨论】:

  • 它们不在 BCPL 或 B 中。
  • 它来自 C,而不是 C++。 C++ 只是保留了它,因为 Stroustrup 不想在 C 和 C++ 之间引入不必要的不​​兼容性。
  • 1976 年,C 中还没有十六进制常量。cs.bell-labs.com/who/dmr/cman.ps

标签: c hex octal


【解决方案1】:

C 是 C++ 和 Java 的祖先,最初是由 Dennis Richie 在 70 年代初在 PDP-8 上开发的。这些机器有一个12-bit address space,因此指针(地址)是 12 位长,并且最方便地用四个 3 位八进制数字在代码中表示(第一个可寻址字是 0000 八进制,最后一个可寻址字是 7777 八进制)。

八进制不能很好地映射到 8 位字节,因为每个八进制数字代表三个位,因此在八进制表示法中总会有多余的位可表示。一个全真位字节(1111 1111)是八进制的 377,但十六进制的 FF。

对于大多数人来说,十六进制更容易在他们的脑海中转换为二进制,因为二进制数通常以八为一组(因为这是一个字节的大小)表示,而八正好是两个十六进制数字,但十六进制表示法会在丹尼斯的时代一直笨拙且具有误导性(暗示能够寻址 16 位)。程序员在使用硬件(每个位通常代表一条物理线路)和按位逻辑(每个位都有程序员定义的含义)时,需要以二进制方式思考。

我认为丹尼斯添加了 0 前缀,作为日常十进制数的最简单可能的变体,并且对于那些早期的解析器来说最容易区分。

我相信十六进制表示法 0x__ 是稍后添加到 C 中的。编译器解析树以区分 1-9(十进制常量的第一个数字)、0(八进制常量的第一个 [无关紧要] 数字)和 0x(表示后续数字中跟随的十六进制常量)要多得多复杂的不仅仅是使用前导 0 作为指示符来从将后续数字解析为八进制而不是十进制。

丹尼斯为什么要这样设计? Contemporary programmers 不理解那些早期的计算机通常是通过物理翻转 CPU 前面板上的开关或使用打孔卡或纸带来切换到 CPU 的指令来控制的;节省几个步骤或说明的所有环境都可以节省大量体力劳动。此外,内存有限且昂贵,因此即使保存几条指令也具有很高的价值。

总结: 0 表示八进制,因为它可以有效地解析并且八进制在 PDP-8 上是用户友好的(至少对于地址操作而言)

0x 表示十六进制可能是因为它是八进制前缀标准的自然且向后兼容的扩展,并且解析起来仍然相对有效。

【讨论】:

    【解决方案2】:

    八进制的零前缀和十六进制的 0x 来自早期的 Unix。

    八进制存在的原因可以追溯到硬件具有 6 位字节的时候,这使得八进制成为自然的选择。每个八进制数字代表 3 位,因此 6 位字节是两个八进制数字。十六进制也是如此,从 8 位字节开始,其中一个十六进制数字是 4 位,因此一个字节是两个十六进制数字。对 8 位字节使用八进制需要 3 个八进制数字,其中第一个数字只能有值 0、1、2 和 3(第一个数字实际上是“四进制”,而不是八进制)。 除非有人开发了一个字节长度为 10 位的系统,否则没有理由使用 base32,因此一个 10 位字节可以表示为两个 5 位“nybbles”。

    【讨论】:

    • 我认为这个问题与语法的起源有关。
    【解决方案3】:

    “新”数字必须以数字开头,才能使用现有语法。

    已建立的实践具有以字母(或其他一些符号,可能是下划线或美元符号)开头的变量名称和其他标识符。所以“a”、“abc”和“a04”都是名字。数字以数字开头。所以“3”和“3e5”是数字。

    当您向编程语言中添加新事物时,您会寻求使它们适合现有的语法、语法和语义,并尝试使现有代码继续工作。因此,您不希望更改语法以使“x34”成为十六进制数或“o34”成为八进制数。

    那么,如何将八进制数字放入此语法中?有人意识到,除了“0”之外,不需要以“0”开头的数字。没有人需要为 123 写“0123”。所以我们使用前导零来表示八进制数字。

    十六进制数字呢?您可以使用后缀,因此“34x”表示 3416。然而,解析器在知道如何解释数字之前必须一直读到数字的末尾(除非它遇到“a”到“f”数字之一,这当然表示十六进制)。解析器“更容易”知道数字是早期的十六进制。但是你仍然必须从一个数字开始,并且已经使用了零技巧,所以我们需要其他东西。选择了“x”,现在我们有十六进制的“0x”。

    (以上内容基于我对解析的理解和一些关于语言开发的一般历史,而不是基于编译器开发人员或语言委员会做出的具体决定的知识。)

    【讨论】:

      【解决方案4】:

      我不知道...

      0 代表 0ctal

      0x 是为了,嗯,我们已经用 0 来表示八进制,并且还有一个十六进制的 x,所以里面也有一个 x

      至于自然进程,最好看看最新的可以加下标的编程语言,例如

      123_27(将_解释为下标)

      等等

      ?

      标记

      【讨论】:

      • 相同。这正是 C 的其余部分是如何“设计”的。
      • x 听起来像 'ex,这是 18 世纪伦敦的“十六进制数字文字”。
      • 哇,我本来打算把这个标记为-1,但后来我看到@detly 的评论,我意识到生活是美好的,虽然这个答案确实以“我不知道”开头并以问号和结尾签名。
      【解决方案5】:

      base-32 有自然的进展吗?

      这就是为什么 Ada 使用 16# 形式来引入十六进制常量、8# 表示八进制、2# 表示二进制等的部分原因。

      不过,我不会太担心自己在基地中需要空间来实现“未来增长”。这不像 RAM 或寻址空间,您需要每一代都增加一个数量级。

      事实上,研究表明八进制和十六进制几乎是二进制兼容的人类可读表示的最佳位置。如果你低于八进制,它开始需要大量的数字来表示更大的数字。如果你高于十六进制,数学表会变得非常大。 Hex 实际上已经有点太多了,但是 Octal 的问题是它不能均匀地放入一个字节中。

      【讨论】:

        【解决方案6】:

        Base32 有一个标准编码。它与Base64 非常相似。但是阅读起来不是很方便。使用十六进制是因为 2 个十六进制数字可用于表示 1 个 8 位字节。八进制主要用于使用12-bit 字节的旧系统。与将原始寄存器显示为二进制相比,它可以更紧凑地表示数据。

        还应注意,某些语言使用 o### 表示八进制,使用 x## 或 h## 表示十六进制,以及许多其他变体。

        【讨论】:

          【解决方案7】:

          我认为0x 实际上是为 UNIX/Linux 世界而来的,并被 C/C++ 和其他语言所采用。但我不知道确切的原因或真正的起源。

          【讨论】:

          • 当它出现在 C 中时,还没有 Linux 这样的东西。我不确定有多少个 Unix 版本。可能只是 AT&T 的。
          • Unix 是用 C 语言编写的汇编和 Linux 吗?
          • 0x 绝对是 post-unix 和 post-C。到 1976 年,UNIX 和 C 都在没有它的情况下发布。它似乎出现在 1978 年的“The C Programming Language”第一版中。
          • C 的创建是为了帮助构建第一个 Unix 操作系统。在早期,C“世界”和 Unix“世界”是同一个世界。
          猜你喜欢
          • 2021-01-29
          • 2019-10-27
          • 2016-09-04
          • 1970-01-01
          • 2012-12-12
          • 1970-01-01
          • 2013-11-07
          • 1970-01-01
          相关资源
          最近更新 更多