问题
I'm translating some Fortran into Javascript and the order of operations for exponents is pretty opaque to me for a particular class of equations.
Here's an example of the Fortran equation:
x = 1+a*b**c*c**d
Exponents in Fortran are designated with the ** operator. This page gives some hints:
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.
So it feels to me like to translate this into, say, Python, you'd end up with something like:
x = 1+a*pow(b,c)*pow(c,d)
But that isn't getting me the answers I'd expect it to, so I wanted to check if that seemed sane or not (because order of operations was never a strong suit of mine even in the best of circumstances, certainly not with languages I am not very familiar with).
Here's another puzzler:
x = a*(1-(1-a)**b)+(1-a)*(a)**(1/b)
Oy! This hurts my head. (Does putting that lone (a) in parens matter?) At least this one has parens, which suggests:
x = a*(1-pow(1-a,b))+(1-a)*pow(a,1/b)
But I'm still not sure I understand this.
回答1:
You can look at this in terms of precedence of operators. **
is a higher precedence than *
, higher than binary +
. The expression 1+a*b**c*c**d
is then like 1+a*(b**c)*(c**d)
.
More formally...
Expressions in Fortran are described by a grammar consisting of primaries and level-1 to level-5 expressions. Let's look at these using the example of the question
x = 1+a*b**c*c**d
the right-hand side of this is the expression of interest. As this is a so-called level-2 expression I'll explain only in terms up to that.
The primaries of this expression are the constant 1
and the variables a
, b
, c
and d
. We also have a number of operators +
, **
and *
.
The primaries are all level-1 expressions, and as there is no defined unary operator here we'll go straight to the level-2 expressions.
A level-2 expression is defined by the rules (quoting F2008 7.1.2.4):
- mult-operand is level-1-expr [ power-op mult-operand ]
- add-operand is [ add-operand mult-op ] mult-operand
- level-2-expr is [ [ level-2-expr ] add-op ] add-operand
where power-op is **
, mult-op *
(or /
) and add-op +
(or -
).
Putting the parsing together we have:
1 + add-operand
1 + ( add-operand * mult-operand )
1 + ( ( a * mult-operand ) * ( mult-operand ) )
1 + ( ( a * ( b ** c ) ) * ( c ** d ) )
As a final note, an expression enclosed in parentheses is a primary. This ensures that the expectation of precedence with parentheses is preserved.
This grammar also explains why a**b**c
is evaluated as a**(b**c)
.
来源:https://stackoverflow.com/questions/45721863/fortran-order-of-operations-for-exponents