八进制数字字面量:何时?为什么?有必要吗?

51

我从未在我的代码中使用过八进制数字,也没有遇到任何使用它的代码(尽管十六进制和位操作除外)。

我大约于1994年开始学习C/C++编程,所以可能对此太年轻了?早期的代码使用八进制吗?C语言通过在数字前添加0来支持这些数字,但是有哪些代码使用这些八进制数字字面量呢?


31
我经常使用它们(以八进制零的形式):if (b < 0) b = 0; - pmg
2
@pmg: 我想知道是否有定义0q1234为非零八进制常量“正确”格式的困难,并明确废除01234并建议编译器产生非致命诊断?实际上,我想看到的是一个通用的基于位的格式0 [[x [0-9A-Fa-f] +] | [q [0-7] +] | [w [0-3] +] | [v [0-1] +]] +,以允许混合使用1-4位字段,因为3位字段并不总是从右侧的3位倍数对齐。 - supercat
今天恰好有些巧合,这个问题出现在了SO的首页上(有人添加了一个答案),而Raymond Chen今天也发布了一篇关于八进制混乱的文章:前导零的诅咒 - Michael Burr
我所见过的唯一用途是在定义文件open()标志和权限时,因为它们通常是从标准参考中复制的。但即使对于这些情况,它们也不比十进制甚至二进制表示更有帮助。 - eckes
1
@supercat Python 3这样做 - 八进制常量的形式为0o1234,而旧的01234形式会导致语法错误。 - glglgl
显示剩余3条评论
13个回答

54

我最近必须编写涉及3位二进制字段的网络协议代码。当你想要调试时,八进制会派上用场。

为了效果,您能告诉我这个字段的3位是什么吗?

0x492492

另一方面,这个数字在八进制中表示为:

022222222

现在,最终以二进制方式(每组三个):

010 010 010 010 010 010 010 010

我在Programmers Exchange的一个类似问题中提到了你的答案,并对其进行了扩展,也许会引起其他对八进制感兴趣的人的兴趣:http://programmers.stackexchange.com/questions/98692/where-are-octals-useful/98733#98733 - Abel
1
没错,但它们通常仅用于使用3位组或其倍数的现有协议。任何新代码和协议通常使用nybbles或其倍数,通常用十六进制表示。 - mirabilos
3
@mirabilos这是一个非常宽泛的说法。没有必要将字段长度锁定为4或8位的倍数--实际上,排除其他长度可能会在协议中产生很多额外开销。也许对于某些应用程序来说这并不重要,但是对于支持性能真正重要的应用程序的协议呢?在这些情况下,当3位字段足以胜任时,您不会选择4位字段。 - Ben Collins
@BenCollins的“normally”并不意味着“不惜一切代价总是如此”。我认为协议开发人员应该理性思考。然而,现代事物(过去几十年来)倾向于使用十六进制而不是八进制。 - mirabilos

37

在现今的技术领域,我只会在Linux文件权限位上遇到八进制字面值。通常,文件权限用3个八进制数字表示,每个数字分别代表文件拥有者、群组和其他用户的权限。

例如,0755(大部分命令行工具也可以简写为755)表示文件拥有者具有完全权限(读取、写入、执行),而群组和其他用户仅具有读取和执行权限。

用八进制表示这些位可以更容易地确定设置的权限。你可以一眼看出0755的含义,但并不清楚493或0x1ed表示什么。


还有像信号量和共享内存这样的IPC资源。http://uw714doc.sco.com/en/SDK_sysprog/_Getting_Semaphores.html#ipc_i8 - An̲̳̳drew
当然,最好使用u=rwx,go=rx来处理,这已经在posix中使用了大约30年。这意味着(u)ser可以读取、写入和执行,而(g)roup和(o)ther只能读取和执行。无需八进制思维。 - jrodman
你只需要输入0就可以遇到它。是的,它本身就是八进制的。请阅读标准第6.4.4.1节整数常量。 - Pryftan

30

来自维基百科

在八进制广泛用于计算机时,IBM主机等系统使用24位(或36位)字。对于这些机器,八进制是二进制的理想缩写,因为八个(或十二个)数字可以简明地显示整个机器字(每个八进制数字涵盖三个二进制数字)。此外,它通过允许使用Nixie管、七段显示器和计算器来省成本,用于操作员控制台;在那里,二进制显示器过于复杂,十进制显示器需要复杂的硬件来转换基数,而十六进制显示器需要显示字母。

然而,所有现代计算平台都使用16、32或64位字节,每个字节由8位组成。在这样的系统上,需要三个八进制数字,最高有效八进制数字不太优雅地表示仅两个二进制数字(并且在一个系列中,相同的八进制数字将代表下一字节中的一个二进制数字)。因此,在编程语言中更常使用十六进制,因为一个十六进制数位涵盖四个二进制数位,所有现代计算平台都有可被四整除的机器字。一些具有2的幂次方字长的平台仍然有指令子字,如果以八进制显示,则更容易理解;这包括PDP-11。现代普及的x86架构也属于这个类别,但在这个平台上几乎不使用八进制。

-亚当


27

我从没在我的代码中使用过八进制数,也没有遇到过使用它的任何代码。

我敢打赌你用过。根据标准规定,以零开头的数字字面量是八进制的。这包括了常见的0。每次你使用或者看到字面量的零,它就是八进制的。奇怪但是真实。 :-)


4
这个说法实际上是不正确的。八进制数以'0'作为标识符开头,就像'0x'不是一个有效的数字一样,'0'也不是一个八进制数,而'00'则是八进制数。 - Luc Bloom
10
我认为你可能误解了。ISO/IEC 9899:201x的第6.4.4.1节规定了字面常量可以采用的形式,其中 0 明确列为八进制常量。此外,十进制常量不能以零开头。您可以在网上查看此标准的草案这里 - Tim
5
@LucBloom 中的 0 实际上是八进制。请参阅 Is 0 a decimal literal or an octal literal? - underscore_d
3
我们可以说字面上的0只是八进制的词汇定义,但实际上数字0同时以所有可能的基数表示。或者也可能没有。 - Petruza
1
除了0以外,无论使用哪个进制,它的表示方式都完全相同。 - Petruza
显示剩余2条评论

9

商业航空使用八进制“标签”(基本上是消息类型ID)在古老的Arinc 429总线标准中。因此,在编写航空电子应用程序时能够以八进制指定标签值是很好的...


7

我也看到过八进制在飞机应答器中的使用。模式3a应答器代码是一个12位数字,每个人都将其处理为4个八进制数字。在维基百科上有更多信息。我知道这与计算机通常无关,但美国联邦航空局也使用计算机 :)


2
我认为这是为了几十年前的航空电子设备的利益而做的,你可以在四个拇指轮上输入代码,这些拇指轮直接将12位值编码成简单的数字逻辑进行顺序传输。由于当时还没有微处理器(或者不想在航空电子应用中增加复杂性),因此没有涉及到微处理器。 - greggo

6

在Unix领域中,chmodmkdir函数非常有用,但除此之外,我想不到任何其他常见的用途。


4

没有世俗的理由去修改一个追溯到语言诞生并存在于无数程序中的标准。我还记得ASCII字符的八进制值,想起A的十六进制值需要思考一下,但它在八进制中是101;数字0是060... ^C是003...

也就是说,我经常使用八进制表示法。

如果你真的想挑战自己,看看PDP-10的单词格式吧...


4

我是通过PDP-11接触到Octal的,而C语言似乎也是如此 :)


(注:Octal是一家IT技术公司)

2
啊,PDP11;我仍然记得许多编码:010446 = MOV R4,-(SP),因为01xxxx = mov;04=R4;46=-(SP)。 - greggo

4

仍然有一堆老的过程控制系统(如Honeywell H4400,H45000等)存在于60年代末和70年代,它们使用24位字及八进制寻址。想想在美国建造最后一个核电站的时间就是一个例子。

更换这些工业系统是一个相当大的工程,因此您可能很幸运在野外遇到其中一个,然后对其壮丽的自定义浮点格式感到惊叹!


4
好的gravatar(头像)...你抓住我了。 - Jared Updike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接