Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带ifort的指数的Fortran运算符优先级错误_Fortran_Operator Precedence_Intel Fortran - Fatal编程技术网

带ifort的指数的Fortran运算符优先级错误

带ifort的指数的Fortran运算符优先级错误,fortran,operator-precedence,intel-fortran,Fortran,Operator Precedence,Intel Fortran,我发现波特兰编译器和英特尔fortran编译器在计算一个简单表达式时表现出了不同的行为,该表达式后面是一个指数,后面是一个乘法。根据我对运算符优先级的理解,我非常确定pgf90(和gfortran)工作正常,但我想听听第二种意见,因为这些事情可能会变得有点棘手 这里是我的代码简化为一个非常基本的形式。当使用ifort运行时,d1=a**-2*b形式的表达式被解释为d1=a**(-2*b)由ifort通过asd1=(a**-2)*b通过pgf90和gfortran。如果我从指数中删除负号,所有三个

我发现波特兰编译器和英特尔fortran编译器在计算一个简单表达式时表现出了不同的行为,该表达式后面是一个指数,后面是一个乘法。根据我对运算符优先级的理解,我非常确定pgf90(和gfortran)工作正常,但我想听听第二种意见,因为这些事情可能会变得有点棘手

这里是我的代码简化为一个非常基本的形式。当使用ifort运行时,
d1=a**-2*b
形式的表达式被解释为
d1=a**(-2*b)
由ifort通过as
d1=(a**-2)*b
通过pgf90和gfortran。如果我从指数中删除负号,所有三个编译器都会将其解释为
d1=(a**2)*b
。如果我把*b改为+b,我也会从这三个方面得到良好的表现

program badvals
  implicit none
  real :: a, b, c1, c2, d1, d2

  a = 2.
  b = 4.

  ! Works with addition following the exponent.
  c1 = a**-2+b
  c2 = a**(-2)+b

  ! Ifort differs with multiplication following negative exponent.
  d1 = a**-2*b
  d2 = a**(-2)*b

  print*, "c1, d1       = ",c1, d1
  print*, "c2, d2       = ",c1, d2
  print*, "c2-c1, d2-d1 = ",c2-c1, d2-d1
end program badvals

!Program output for ifort v13.0.1.117: (either -O0 or -fast):
! c1, d1       =    4.250000      3.9062500E-03
! c2, d2       =    4.250000       1.000000
! c2-c1, d2-d1 =   0.0000000E+00  0.9960938

!Program output for pgf90 v12.10-0: (either -O0 or -fast):
! c1, d1       =     4.250000        1.000000
! c2, d2       =     4.250000        1.000000
! c2-c1, d2-d1 =     0.000000        0.000000

!Program output for gfortran v4.1.2: (either -O0 or -O3):
! c1, d1       =    4.250000       1.000000
! c2, d2       =    4.250000       1.000000
! c2-c1, d2-d1 =    0.000000       0.000000

这些差异背后是否有历史渊源,因此应将其视为“特征”?或者,这是英特尔方面的一个彻头彻尾的错误吗?

在搜索web时,我发现不允许两个连续的运算符。因此,解释而不是拒绝这个表达是语言的延伸。不同的编译器供应商实现了不同的扩展

事实上,当我将gfortran与限制性编译器选项一起使用时,它拒绝了以下代码示例:

badvals.f90:9.11:
  c1 = a**-2+b
           1
Error: Extension: Unary operator following arithmetic operator (use parentheses) at (1)
badvals.f90:13.11:

  d1 = a**-2*b
           1
Error: Extension: Unary operator following arithmetic operator (use parentheses) at (1)
类似地,带有限制性编译器选项的ifort提供以下功能:

badvals.f90(9): warning #7026: Non-standard extension
  c1 = a**-2+b
----------^
badvals.f90(13): warning #7026: Non-standard extension
  d1 = a**-2*b
----------^
因此: 1) 使用编译器的警告和错误选项非常有用, 2) 与其说是bug,不如说是扩展,
3) 即使该语言允许使用此表达式,gfortran的建议也很好——即使不需要,也要使用括号以保持清晰。

“不允许使用两个连续运算符”需要一些限定条件-它适用于此处,因为第二级表达式(算术表达式)的语法规则,但通常不适用于<代码>待办事项或。不to_be是可以的(在莎士比亚的Fortran语言中很常见),你也可以在其中插入一个定义的一元运算符。如果OP需要扩展的正式描述,他们可以读取。这些限制性选项是什么?因此,根据MSB和IanH的响应,这将是ifort的一个“功能”。一般来说,我从中得到的是,我需要在我的思维中加入“不要将两个算术运算符放在一起”的规则。和往常一样,要慷慨地使用括号。IanH提供的链接对于理解ifort的想法非常有帮助。将*更改为a+时,我看到的不同行为是因为一元+-优先级介于*和二进制+-之间。