I have two questions regarding the following legacy code segment:
do i=1, n_total, increment diff = array(i) - x1 if (diff < 0.0_dp) then ! do something go to 10 else if (diff == 0.0_dp) then ! do something go to 10 else if (diff > 0.0_dp) then ! do something go to 10 end if end do ! We fell out of do loop, write error and stop write(unit=6,fmt='(''No Match'')') stop 10 continue
1. Does Fortran 1990/95/03/08 provide a specific keyword or state variable (maybe something like END_STATUS) to check if a do loop completes without a branch or break or, in the case above, do you have to check the value of i against n_total? The first approach would allow a standard set of code which would be independent of the index and terminal variable.
2. In the code above, would it be better to replace the go to statements with break and enclosed the error message in an if statement? Any performance difference between the two approaches? What would be best practice? Any other approach would be welcome.
loopblock: block do i=1, n_total, increment diff = array(i) - x1 if (diff < 0.0_dp) then ! do something exit loopblock else if (diff == 0.0_dp) then ! do something exit loopblock else if (diff > 0.0_dp) then ! do something exit loopblock end if end do ! We fell out of do loop, write error and stop write(unit=6,fmt='(''No Match'')') stop end block loopblock ! Execution continues here if something found
So far the "how" has been covered, but unless you have more things going on in the DO loop, the "why bother" question applies.
As it is, the DO loop will be executed only once, and the jump taken, because a real variable cannot be anything other than < 0, = 0 or > 0, unless you wish to cover the case where some of the variables involved are undefined.
Note under floating-point precision, the following statement is almost meaningless:
(diff == 0.0_dp) then
The none of the above condition is: (isnan(diff))
FortranFan, (diff == 0.0_dp) almost meaningless
In the O.P's case, exact equality may be desired, chauvjo will have to determine this. In many applications it may be appropriate to use
real(dp), parameter :: AlmostZero = 1.0D-30 ! user specified ... if (diff < -AlmostZero) then ! do something exit loopblock else if (diff > AlmostZero) then ! do something exit loopblock else then ! -AlmostZero : AlmostZero ! do something exit loopblock end if
The above assumes NAN is never presented
The code presented has some of the flavor of translation of arithmetic IF. Perhaps it assumes that abrupt underflow (/Qftz) is set so as to avoid accidental production of subnormals in place of zeroes.
Tim P.: You are correct. The code segment I posed was a translation of an arithmetic IF.
Jim: You have raised another issue on how best to handle an floating point equivalence check in an if statement. Since this is off topic, I will start a new threat called "floating point equivalence check"