Fortran指数运算顺序

Fortran指数运算顺序,fortran,operator-precedence,Fortran,Operator Precedence,我正在将一些Fortran语言翻译成Javascript,对于一类特殊的方程,指数的运算顺序对我来说是非常不透明的 下面是Fortran公式的一个示例: x = 1+a*b**c*c**d Fortran中的指数用**运算符指定。给出了一些提示: 算术表达式根据以下优先级规则进行计算: 首先执行所有的求幂运算;从右到左执行连续的求幂运算 接下来将按照从左到右的顺序执行所有乘法和除法 所以我觉得把它翻译成Python,你会得到这样的结果: x = 1+a*pow(b,c)*pow(c,d)

我正在将一些Fortran语言翻译成Javascript,对于一类特殊的方程,指数的运算顺序对我来说是非常不透明的

下面是Fortran公式的一个示例:

x = 1+a*b**c*c**d
Fortran中的指数用**运算符指定。给出了一些提示:

算术表达式根据以下优先级规则进行计算:

  • 首先执行所有的求幂运算;从右到左执行连续的求幂运算
  • 接下来将按照从左到右的顺序执行所有乘法和除法
所以我觉得把它翻译成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中的表达式由一个由原语和一至五级表达式组成的语法描述。让我们用问题的例子来看看这些

x = 1+a*b**c*c**d
右边是兴趣表达。因为这是一个所谓的二级表达式,所以我将仅从这个角度进行解释

这个表达式的原数是常量
1
和变量
a
b
c
d
。我们还有许多运算符
+
***
*

原色都是一级表达式,因为这里没有定义的一元运算符,所以我们直接转到二级表达式

2级表达式由规则定义(引用F2008 7.1.2.4):

  • 多操作数是级别1-expr[幂运算多操作数]
  • 加法操作数是[加法操作数乘法运算]乘法操作数
  • 二级表达式为[[二级表达式]加法运算]加法操作数
如果power op为
**
,则多个op
*
(或
/
)并添加op
+
(或
-

将解析放在一起,我们有:

  • 1+添加操作数
  • 1+(添加操作数*多个操作数)
  • 1+((a*多操作数)*(多操作数))
  • 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

这是一段相当复杂的代码的一部分——在本例中,a、b和d都是常数(5.9、.09和3.8),而c是一个可以变化的比率(在这个特定的约束条件下,它至少大于1.0)。至于我期望它评估什么-我没有任何这些。我所知道的就是最终的输出(包括许多这样的方程)是否有意义,而现在它没有意义;不管是不是因为这个原因,我不知道,但这似乎是目前最有可能的罪魁祸首。(我认为很明显,我没有编写最初的FORTRAN。可以说,它是遗留代码的一部分,它的作者不在。他们确实提供了一个“详细的”这个方程的版本,看起来应该和我的计算方法一样,但它是用打字机打印的,是从缩微胶片上扫描的,所以我对指数的正确性没有太多信心。)当你在看单精度常数的表达式时,在pow()力加倍的语言中,可能很难精确地复制它们。从f90开始,Fortran原则上需要避免非标准计算的选项(但默认情况下仍有一定的自由度)。可以在C中使用powf。不确定javascript。但是,请记住,编译器可以自由地重新排序操作。标准上说,,一旦建立了数值内在运算的解释,处理器可以计算任何数学上等价的表达式,前提是不违反括号的完整性。两个数值类型的表达式在数学上是等价的,如果它们的原数的所有可能值的数学值都相等。然而,数值类型的数学等价表达式可能会产生不同的计算结果。”@SteveLionel,这是关于潜在数值差异的评论吗(我在回答中没有提到,但这是与整个问题相关的有用信息),或者你认为我可以改进我的内容吗?@francescalus我的评论是为了补充你的答案,因为这是Fortran用户之间的一个常见误解。OP提到了不同的答案,认识到数学结果和计算结果之间的差异很重要。