Fortran order of operations for exponents

|▌冷眼眸甩不掉的悲伤 提交于 2021-01-27 18:51:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!