指数的 Fortran 运算顺序
Fortran order of operations for exponents
我正在将一些 Fortran 语言翻译成 Javascript,对于特定的 class 方程,指数的运算顺序对我来说非常不透明。
这是 Fortran 方程式的示例:
x = 1+a*b**c*c**d
Fortran 中的指数用 ** 运算符指定。 This page 给出了一些提示:
Arithmetic expressions are evaluated in accordance with the following priority rules:
- All exponentiations are performed first; consecutive exponentiations are performed from right to left.
- All multiplication and divisions are performed next, in the order in which they appear from left to right.
所以我觉得把它翻译成,比如说,Python,你最终会得到这样的东西:
x = 1+a*pow(b,c)*pow(c,d)
但这并没有得到我期望的答案,所以我想检查一下这是否合理(因为即使在最好的情况下,操作顺序也不是我的强项,当然不是我不太熟悉的语言)。
这是另一个谜题:
x = a*(1-(1-a)**b)+(1-a)*(a)**(1/b)
哎呀!这伤了我的头。 (把那个单独的 (a) 放在括号里重要吗?)至少这个有括号,这表明:
x = a*(1-pow(1-a,b))+(1-a)*pow(a,1/b)
但我仍然不确定我是否理解这一点。
你可以从运算符的优先级来看这个。 **
的优先级高于 *
,高于二进制 +
。表达式 1+a*b**c*c**d
就像 1+a*(b**c)*(c**d)
.
更正式...
Fortran 中的表达式由 primaries 和 level-1 到 level-5[ 组成的文法描述=75=] 表达式。让我们用问题的例子来看这些
x = 1+a*b**c*c**d
右边是感兴趣的表达。因为这是所谓的 2 级表达式,所以我将只解释到这一点。
此表达式的主要元素是常量 1
和变量 a
、b
、c
和 d
。我们还有许多运算符 +
、**
和 *
.
初选都是一级表达式,这里没有定义的一元运算符直接进入二级表达式
二级表达式由规则定义(引用F2008 7.1.2.4):
- 多操作数是 level-1-expr [power-op 多操作数]
- 加操作数是[加操作数多操作]多操作数
- level-2-expr 是 [ [ level-2-expr ] add-op ] add-operand
其中 power-op 是 **
,mult-op *
(或 /
) 和 add-op +
(或 -
)。
将解析放在一起我们有:
1 + add-operand
1 + ( add-operand * mult-operand )
1 + ( ( a * mult-operand ) * ( mult-operand ) )
1 + ( ( a * ( b ** c ) ) * ( c ** d ) )
最后一点,括号中的表达式是主要表达式。这可确保保留带括号的优先级期望。
这个语法也解释了为什么 a**b**c
被评估为 a**(b**c)
。
用于说明(评论中没有 HTML)。
Fortran:3**j**a**1
=== 数学:3ja1
1+a*b**c*c**d
=== 1 + a×bc×cd
我正在将一些 Fortran 语言翻译成 Javascript,对于特定的 class 方程,指数的运算顺序对我来说非常不透明。
这是 Fortran 方程式的示例:
x = 1+a*b**c*c**d
Fortran 中的指数用 ** 运算符指定。 This page 给出了一些提示:
Arithmetic expressions are evaluated in accordance with the following priority rules:
- All exponentiations are performed first; consecutive exponentiations are performed from right to left.
- All multiplication and divisions are performed next, in the order in which they appear from left to right.
所以我觉得把它翻译成,比如说,Python,你最终会得到这样的东西:
x = 1+a*pow(b,c)*pow(c,d)
但这并没有得到我期望的答案,所以我想检查一下这是否合理(因为即使在最好的情况下,操作顺序也不是我的强项,当然不是我不太熟悉的语言)。
这是另一个谜题:
x = a*(1-(1-a)**b)+(1-a)*(a)**(1/b)
哎呀!这伤了我的头。 (把那个单独的 (a) 放在括号里重要吗?)至少这个有括号,这表明:
x = a*(1-pow(1-a,b))+(1-a)*pow(a,1/b)
但我仍然不确定我是否理解这一点。
你可以从运算符的优先级来看这个。 **
的优先级高于 *
,高于二进制 +
。表达式 1+a*b**c*c**d
就像 1+a*(b**c)*(c**d)
.
更正式...
Fortran 中的表达式由 primaries 和 level-1 到 level-5[ 组成的文法描述=75=] 表达式。让我们用问题的例子来看这些
x = 1+a*b**c*c**d
右边是感兴趣的表达。因为这是所谓的 2 级表达式,所以我将只解释到这一点。
此表达式的主要元素是常量 1
和变量 a
、b
、c
和 d
。我们还有许多运算符 +
、**
和 *
.
初选都是一级表达式,这里没有定义的一元运算符直接进入二级表达式
二级表达式由规则定义(引用F2008 7.1.2.4):
- 多操作数是 level-1-expr [power-op 多操作数]
- 加操作数是[加操作数多操作]多操作数
- level-2-expr 是 [ [ level-2-expr ] add-op ] add-operand
其中 power-op 是 **
,mult-op *
(或 /
) 和 add-op +
(或 -
)。
将解析放在一起我们有:
1 + add-operand
1 + ( add-operand * mult-operand )
1 + ( ( a * mult-operand ) * ( mult-operand ) )
1 + ( ( a * ( b ** c ) ) * ( c ** d ) )
最后一点,括号中的表达式是主要表达式。这可确保保留带括号的优先级期望。
这个语法也解释了为什么 a**b**c
被评估为 a**(b**c)
。
用于说明(评论中没有 HTML)。
Fortran:3**j**a**1
=== 数学:3ja1
1+a*b**c*c**d
=== 1 + a×bc×cd