为什么求幂的优先级低于一元加减的优先级?
Why is the precedence of exponentiation lower than that of unary plus minus?
大多数语言,例如 Fortran、Python、Ruby、Perl、Awk 等,定义求幂运算符的优先级高于一元加号和减号的优先级。这会产生以下结果:
In [1]: -2**1
Out[1]: -2
In [2]: -2**2
Out[1]: -4
Ksh、bash、zsh 等 Shell 将这两个运算符的优先级颠倒过来。这导致了令人惊讶的结果:
$ echo $((-2**1))
-2
$ echo $((-2**2))
4
Question: Why do shells have this particular precedence order? I assume this is genealogical based ksh > bash > zsh
. But still ..
注意:求幂不是POSIX
的一部分
注:其他languages/interpreters存在类似的优先顺序如bc
、tcl
相关问题:
- Why does Ruby `**` operator have higher precedence than unary `-`?
根据Wikipedia,数学约定是一元减号的优先级低于指数。有些编程语言遵循这一点,有些则不然。
但是上面的文章还给出了科学出版物中使用的不同数学符号约定的例子1;例如乘法和除法不同写法的优先级
你问:为什么?
嗯,在大多数情况下,并没有明确的理由说明为什么特定的语言设计者会做出特定的选择;查看 this Q&A 的答案。但是,我们当然不能证明任何特定的优先系统从理论的角度来看都是“正确的”。
一般来说,PL 优先系统的指导原则似乎是:
- 尽量与该语言的祖先保持一致。
- 尽量与感知的数学惯例保持一致。
- 做当时“感觉正确”的事情。
结果不一致。
幸运的是:
人们倾向于习惯他们大部分时间使用的语言的怪癖,并且
求幂运算符不常使用2,一元减号就更少用了。
所以这通常并不重要。 (除非有人在具有巨大影响/后果的环境中犯错。即便如此,也应该有 流程 来处理人为错误。)
bash
中表达式求值的运算符优先级记录为基于 C 运算符优先级。 (参见 man bash
。)C 没有求幂运算符,但它确实使一元 +
和 -
的优先级高于乘法和除法。
因此为了与 C 保持一致,bash 实现者需要将 **
的运算符优先级置于 *
、/
和 [=17= 之上] 及以下一元 -
。 (将 **
置于一元 -
之上违背了 C 的明确意图......即一元 -
高于所有其他算术运算符。)
如果您真正的问题不是“他们为什么这样做”而是“原因是否已记录”,您可能需要浏览开发人员邮件列表、源代码存储库等以寻找线索。或者问问设计师……虽然他们可能记不清楚原因。
1 - 如果数学家不能在符号上保持一致,为什么编程语言设计师也不能保持一致?
2 - 事实上,许多编程语言甚至不支持求幂运算符。
大多数语言,例如 Fortran、Python、Ruby、Perl、Awk 等,定义求幂运算符的优先级高于一元加号和减号的优先级。这会产生以下结果:
In [1]: -2**1
Out[1]: -2
In [2]: -2**2
Out[1]: -4
Ksh、bash、zsh 等 Shell 将这两个运算符的优先级颠倒过来。这导致了令人惊讶的结果:
$ echo $((-2**1))
-2
$ echo $((-2**2))
4
Question: Why do shells have this particular precedence order? I assume this is genealogical based
ksh > bash > zsh
. But still ..
注意:求幂不是POSIX
的一部分注:其他languages/interpreters存在类似的优先顺序如bc
、tcl
相关问题:
- Why does Ruby `**` operator have higher precedence than unary `-`?
根据Wikipedia,数学约定是一元减号的优先级低于指数。有些编程语言遵循这一点,有些则不然。
但是上面的文章还给出了科学出版物中使用的不同数学符号约定的例子1;例如乘法和除法不同写法的优先级
你问:为什么?
嗯,在大多数情况下,并没有明确的理由说明为什么特定的语言设计者会做出特定的选择;查看 this Q&A 的答案。但是,我们当然不能证明任何特定的优先系统从理论的角度来看都是“正确的”。
一般来说,PL 优先系统的指导原则似乎是:
- 尽量与该语言的祖先保持一致。
- 尽量与感知的数学惯例保持一致。
- 做当时“感觉正确”的事情。
结果不一致。
幸运的是:
人们倾向于习惯他们大部分时间使用的语言的怪癖,并且
求幂运算符不常使用2,一元减号就更少用了。
所以这通常并不重要。 (除非有人在具有巨大影响/后果的环境中犯错。即便如此,也应该有 流程 来处理人为错误。)
bash
中表达式求值的运算符优先级记录为基于 C 运算符优先级。 (参见 man bash
。)C 没有求幂运算符,但它确实使一元 +
和 -
的优先级高于乘法和除法。
因此为了与 C 保持一致,bash 实现者需要将 **
的运算符优先级置于 *
、/
和 [=17= 之上] 及以下一元 -
。 (将 **
置于一元 -
之上违背了 C 的明确意图......即一元 -
高于所有其他算术运算符。)
如果您真正的问题不是“他们为什么这样做”而是“原因是否已记录”,您可能需要浏览开发人员邮件列表、源代码存储库等以寻找线索。或者问问设计师……虽然他们可能记不清楚原因。
1 - 如果数学家不能在符号上保持一致,为什么编程语言设计师也不能保持一致?
2 - 事实上,许多编程语言甚至不支持求幂运算符。