Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fortran operator precedence error for exponent with ifort

I am getting different behavior between Portland and Intel fortran compilers when evaluating a simple expression with an exponent followed by a multiply. I am pretty sure that pgf90 (and gfortran) are working correctly based on my understanding of operator precedence, but I would like a second opinion since these things can get a bit tricky.

Here is my code simplified down to a very basic form. When run with ifort the expression of the form d1=a**-2*b gets interpretted as d1=a**(-2*b) by ifort by as d1=(a**-2)*b by pgf90 and gfortran. If I remove the negative sign from the exponent, all three compilers interpret this as d1=(a**2)*b. If I change *b to +b I also get good behavior from all three.

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

Is there a history behind these differences so that they should be considered a "feature"? Or, is this an outright bug on Intel's part?

like image 921
William Gustafson Avatar asked Mar 14 '13 17:03

William Gustafson


People also ask

Which operator has the highest precedence in fortran?

Certain operators have higher precedence than others; for example, the multiplication operator has higher precedence than the addition operator. For example x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has higher precedence than +, so it first gets multiplied with 3*2 and then adds into 7.

Is Ifort faster than Gfortran?

The ifort-compiled executable runs five times faster than the > gfortran-compiled executable on my Intel Xeon CPU.

How do you use power in Fortran?

In addition to addition +, subtraction -, multiplication * and division /, Fortran has an exponential operator **. Thus, raising X to the Y-th power is written as X**Y. For example, the square of 5 is 5**2, and the square root of 5 is 5**0.5. The exponential operator has the highest priority.


1 Answers

Searching the web, I find that statement that two consecutive operators are not allowed. Therefore interpreting rather than rejecting this expression is an extension to the language. That extension has been implemented differently by different compiler vendors.

Indeed, when I use gfortran with restrictive compiler options, it rejects this code example:

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)

Similarly, ifort with restrictive compiler options provides the following:

badvals.f90(9): warning #7026: Non-standard extension
  c1 = a**-2+b
----------^
badvals.f90(13): warning #7026: Non-standard extension
  d1 = a**-2*b
----------^

So: 1) using the warning and error options of the compiler can be very helpful, 2) its more of an extension than a bug, 3) even if this expression were allowed by the language, gfortran's advice is good -- use parentheses for clarity even if not required.

like image 179
M. S. B. Avatar answered Sep 30 '22 02:09

M. S. B.