【发布时间】:2013-03-14 17:19:43
【问题描述】:
在使用指数后跟乘法计算简单表达式时,我在 Portland 和 Intel fortran 编译器之间得到了不同的行为。根据我对运算符优先级的理解,我很确定 pgf90(和 gfortran)可以正常工作,但我想要第二个意见,因为这些事情可能会有点棘手。
这是我的代码简化为一个非常基本的形式。当使用 ifort 运行时,d1=a**-2*b 形式的表达式被 ifort 解释为 d1=a**(-2*b),被 pgf90 和 gfortran 解释为 d1=(a**-2)*b。如果我从指数中删除负号,所有三个编译器都将其解释为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
这些差异背后是否有历史,因此它们应该被视为“特征”?或者,这是否是英特尔的一个彻头彻尾的错误?
【问题讨论】:
-
因此,根据 MSB 和 IanH 的响应,这将是 ifort 的“功能”。总的来说,我从中得到的是,我需要将“不要将两个算术运算符放在一起”的规则添加到我的想法中。和往常一样,要慷慨地使用括号。 IanH 提供的链接对于理解 ifort 的想法非常有帮助。我在将 * 更改为 + 时看到的不同行为是因为一元 +- 优先级介于 * 和二元 +- 之间。
标签: fortran operator-precedence intel-fortran