Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28710 Discussions

if ( i .gt. 1 .and. x(i-1) .gt. 5.0 )

Wen_C_
Beginner
1,156 Views

The new compiler prompts error when executing the following statements, which worked on very old MS Power Station:

do i=1,10

if ( i .gt. 1 .and. x(i-1) .gt. 5.0 ) then

write(*,*) i, x(i-1)

end if

end do

In the first loop, i=1, x(i-1) = x(0) --> Error, subscript zero

According to the Fortran Logical .and. rule, it evaluates from Left to Right,

In the first loop, i .gt. 1 is NOT true, then x(i-1) will not be evaluated. So, old fortran did not create problem, but new fortran does.  It is easy to fix this problem, but can anyone tell me what is the logical behind this ?  It seems that C evaluates this logical expression from right to left ?  But Fortran is from left to right ?

Thanks,

0 Kudos
10 Replies
Steven_L_Intel1
Employee
1,156 Views

The standard says: "Once the interpretation of a logical intrinsic operation is established, the processor may evaluate any other expression that is logically equivalent, provided that the integrity of parentheses in any expression is not violated." The compiler can evaluate either operand of the .and. first, there is no left-to-right rule in Fortran. The standard also says "It is not necessary for a processor to evaluate all of the operands of an expression, or to evaluate entirely each operand, if the value of the expression can be determined otherwise."

0 Kudos
Walt_Brainerd
Beginner
1,156 Views

To clarify a little more, there is a left-to-right rule to determine the semantics/meaning/interpretation of expressions with mulitple operators of the same precedence.

For example: a / b * c means a divided by b, with the result multiplied by c.

Once the *meaning* has been established, the rules Steve quoted come in to play, allowing the compiler to evaluate an equivalent expression (c * a / b, for example, but *not* a / (b * c).

0 Kudos
TimP
Honored Contributor III
1,156 Views

a/(b*c) is a valid alternative evaluation of a/b/c, as stated on p.221 of "Fortran 2003 Handbook"  (quoting a section which has been in every version of Fortran standard).  Did you mean to say that c/b*a would not be a valid alternative for a/b*c ?  (I don't know the answer to that.) 

The explicitly stated validity of replacing a/5.0 by 0.2*a seems to imply validity of some other invert-and-multiply replacements which ifort performs in the absence of -Qprec-div -Qprec-sqrt (but maybe not those which could incur over/underflow?).  But that's just my impression; was there a committee interpretation? 

As to the original question, the only Fortran compiler I ever saw which applied C-style shortcut evaluation was f2c, which accomplished it by a literal translation to the C code which the poster appears to have in mind.  At least by the time Digital Fortran was put forward as the successor of PowerStation, there were cases where logical expressions were optimized without sequencing.

0 Kudos
Steven_L_Intel1
Employee
1,156 Views

And for completeness, Fortran does not specify short-circuit evaluation the way C does. A compiler can choose to do that, but it can choose not to.

0 Kudos
Walt_Brainerd
Beginner
1,156 Views

Yes: a/(b*c) is a valid alternative evaluation of a/b/c.

Those guys that wrote the F2003 Handbook really know their stuff :-).

And no: I did mean to say that c/b*a *would* be a valid alternative for a/b*c

And yes: x/5.0 can be evaluated as 0.2*x

All of these (and all the things Steve said) have been true for decades.

Thus a .and. b can be evaluated (computed) by evaluating a first, b first, or both (or neither is there is a way to determine the answer by other means). This has significant consequences in the original post example and when a or b contain function calls with side effects.

0 Kudos
mecej4
Honored Contributor III
1,156 Views

When I learned algebra, "a/bc" meant "a/(b X c)" in standard mathematics and physics books and articles. Then along came Fortran and changed the interpretation, and that interpretation is now propagating back into mathematics and physics publications. Perhaps, in a few years, someone will accuse Goudsmit and Uhlenbeck of an error, since they decided in 1925 that the electron has its own unit : ħ =h /2π. (i.e., h / the angle swept by running once on a circle).

0 Kudos
Walt_Brainerd
Beginner
1,156 Views

I agree completely with your comments.

I have always thought that the precedence of * should be higher than /, but, unfortunately, the only way to fix this is to time travel back to the 1950s and make that change. Then, a/b*c whould mean the same as a/(b*c), not (a/b)*c as it is now.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,156 Views

>>I have always thought that the precedence of * should be higher than /, but

Not necessarily so. When the compiler can determine or approximate the relative magnitude of the numbers, then the choice of order can reduce the error in approximation. Though the programmer, when applicable, should use parens and options to enforce evaluation to use the parens.

Jim Dempsey

0 Kudos
Walt_Brainerd
Beginner
1,156 Views

I don't understand your comment.

I was talking about an imaginary alternative to the Fortran semantics for a/b*c.

Multiplying by c and dividing by c are quite different and have nothing to do with approximations, errors, etc.

0 Kudos
mecej4
Honored Contributor III
1,156 Views

I am to blame for slightly shifting the context in #7 to talk about the longstanding (and now, threatened) convention in mathematics and physics, and about operations with real numbers (with infinite precision).

0 Kudos
Reply