为什么这么多语言将以0开头的数字视为八进制?


21

我读过八进制在哪里有用?八进制似乎曾经是有用的。

许多语言将以0开头的数字视为八进制,因此文字010实际上是8。其中一些是JavaScript,Python(2.7)和Ruby。

但是我真的不明白为什么这些语言需要八进制,尤其是当这种符号更可能的用法是表示带有多余0的十进制数字时。

JavaScript是一种客户端语言,八进制似乎毫无用处。从其他意义上讲,这三个都相当现代,我认为不会有太多使用八进制表示法的代码通过删除此“功能”而被破坏。

因此,我的问题是:

  • 这些语言是否支持八进制文字?
  • 如果八进制文字是必需的,为什么不使用类似0o10?为什么要复制覆盖更有用用例的旧符号?

24
您会接受“在面试中迷惑年轻人”的答案吗?
yannis 2014年

11
符合C语法+盲目复制
棘轮怪胎2014年

1
@Manishearth C从其祖先那里继承了它。Java拥有它,因为C拥有它。大多数其他人都有它,因为C和Java都有它。
Ingo 2014年

2
人们仍然看到八进制Unix文件的权限发生了变化:chmod用户,组和其他三个位的组分别为0666或0777,即读,写,可执行文件。
乔普·艾根

3
@Llepwryd在较旧的浏览器中,parseInt('010')确实确实返回了8,因此所有要始终使用的建议parseInt(foo, 10)(对我来说仍然是一种习惯)
Izkata 2014年

Answers:


34

盲目复制C,就像棘轮怪胎在他的评论中所说的那样

如今,绝大多数“语言设计师”除了C及其副本(C ++,Java,Javascript,PHP以及其他几十个我从未听说过的)外,再也没有看到其他东西。他们从未接触过FORTRAN,COBOL,LISP,PASCAL,Oberon,FORTH,APL,BLISS,SNOBOL等。

曾几何时,在计算机科学课程中必须使用多种编程语言,但这不包括将C,C ++和Java视为三种独立的语言。

在早期使用八进制是因为它使读取二进制指令值更容易。例如,PDP-11 BASICALLY具有一个4位操作码,2个3位寄存器号和2个3位访问机制字段。用八进制表示这个词使一切显而易见。

由于C与PDP-11的早期联系,因此包含八进制表示法,因为八进制表示法在当时的PDP-11上非常普遍。

其他机器的指令集不能很好地映射到十六进制。CDC 6600有一个60位字,每个字通常包含2至4条指令。每个指令为15或30位。

至于读写价值,这是一个解决问题,至少在国防工业中,这是众所周知的行业最佳实践。您记录文件格式。记录格式时没有任何歧义,因为无论您查看的是十进制数字,十六进制数字还是八进制数字,文档都会告诉您。

另请注意:如果您的I / O系统默认默认为前导0(表示八进制),则必须在输出上使用其他约定来表示十六进制值。这不一定是胜利。

我个人认为,Ada表现最好:2#10010010#,8#222#,16#92#和146都代表相同的值。(这可能会使我至少获得三票赞成票,只是为了提及Ada。)


11
拒绝您提及Ada ...开个玩笑
kufi 2014年

12
我很好奇,您是怎么想到这个数字的呢?这个数字远远超过50%的“语言设计师”,为什么会引用这种恐慌呢?-除了C后裔外,没有其他经验。我度过了十六年的美好时光,每天与专业的语言设计师交谈,但没有一个能与您的描述相符。
埃里克·利珀特

如果我没记错的话,Javascript被描述为“我们希望在浏览器中执行lisp”以使其设计者感兴趣……
Izkata 2014年

2
@Izkata:确实,Waldemar Horwat曾经告诉我,他认为JavaScript本质上是一种类似于C的语法的Common Lisp。实际上,Waldemar定义了元语言,在Common Lisp中为其元语言编写了解释器,然后在其元语言中编写了JavaScript规范,从而使他能够实际运行该规范。这是一个聪明的技术。
埃里克·利珀特

为什么使用0?使用非数字字符是否有意义?ANSI标准是否没有预见到由以10为基数的数字引起的错误?
老巴德曼·格雷(Badman Gray)2015年

6

他们从C那里得到。为什么要复制?因为所有这三个的基本实现都在C中。Python的默认实现是CPython。Ruby最初也是用C构建的。Javascript是这里最有趣的情况。它在浏览器中运行。想猜猜第一个Web浏览器是用什么编写的?

那么为什么所有这三种语言都用C语言实现?因为它们都起源于UNIX系统。因此,这是由生态系统驱动的惯例案例。Perl也这样做。如果Lua使用整数而不是double, Lua可能会这样做。

因此,这是用C语言编写这些语言的环境的问题,以便它们采用C的约定。Visual Basic是一个很好的支持推论,它使用&O代替。就需要它而言,似乎比其他任何东西都更像是一个泄漏的抽象转换约定。


Mosaic是否支持JavaScript?如果没有,提及它有什么关系?
svick

2
@svick这是Netscape Navigator的基准。
世界工程师

2

一致性具有价值。如果您不能可靠地确定数字的转换方式,那么在不同的上下文中使用值会遇到实际的问题。

这也意味着您不必编写自己的解析器。使用经过良好测试的库例程具有很大的价值。

同样,如果您不支持前导0语法,那么您将没有简单的方法来写入八进制值。

尽管我们不像以前那样依赖八进制数,但它们仍然很有价值。虽然可以用十六进制数获得相同的结果,但在某些情况下八进制更易于理解。

到目前为止,我只看到十进制数字前导零的一种用法。即在显示和输入固定长度的十进制字段(如标识号)中。自从我看到类似的字段以零开头以来已经有好几年了。尽管这将可用值减少了10%,但它消除了用户在输入前导零时经常会忽略它们的问题。


3
前导零的字段是字符串,具有各自含义的视觉表示形式,而不是数字。
Pieter B

1
+1认为chmod 438 ./myfile糟糕!
Ingo 2014年

2
为什么不允许0o10语法?我相信Python支持。您始终可以采用一种简单的方式来写入八进制值,而不会使数字不再是普通数字。我见过人们尝试在代码中使用尾随零来进行对齐和易于操作,并被八进制表示法所
困扰

我能理解一种渴望,除了二进制和十六进制之外,还有一种写八进制值的方法。我还可以理解,031如果程序员使用使用后一种实现的语言编写的代码进行复制,那么将编译器解释为万圣节(10月31日)而不是圣诞节(12月25日)可能会带来一些风险。但是,我看不出有什么原因,为什么一种语言无法通过0q31在需要八进制时支持作为表示法来实现两全其美,或者为什么在以0t025十进制为基数的情况下允许带有前导零的宏粘贴值,并且简单地在没有基础说明符的情况下禁止前导零。
超级猫

@supercat使用前导0表示八进制日期至少可以支持您的青年时代。经常使用该字符的情况是这些位具有重要性,并且仅将该数字解释为十进制数字时才适用于小于8的值。添加其他字符(包括十进制数字中的前导零)可能比帮助更令人困惑。 。我肯定会质疑为什么将日期写为012 031、010 031或012025。– BillThor 2014
41
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.