Author Message
stfark1

Joined: 02 Sep 2008
Posts: 174 Posted: Tue Mar 24, 2015 7:02 pm    Post subject: Logical Comparisons Have several situations where the FTN compiler warns about logical comparisons. Given the following statement: ALL VARIABLES A-H, O-Z ARE DECLARED DOUBLE PRECISION, THE VARIABLE IQUAVR IS INTEGER IQUAVR = 0 C IF (XMIDLH .NE. FMAP .AND. * XCOORD .LE. XMIDLH .AND * XMINTS .EQ. XMAXTS .AND. * YCOORD .GE. FLT0) IQUAVR = 1 THE LOGICAL RESULT IS THAT IQUAVR = 0, THE VARIABLES ARE ASSIGNED AS FOLLOWS: XMIDLH = 1.31750000 FMAP = .000000074 XCOORD= 1.31750000 XMINTS = 1.00000000 XMAXTS = 1.00000000 YCOORD = 1.0000000 FLT0 = 0.0000000 THE OBVIOUS SOLUTION SHOULD BE THAT IQUAVR = 1 AFTER THE COMPARISON BUT IT ACTUALLY RESULTS IN IQUAVR = 0 THE COMPILER WARNS ABOUT LOGICAL COMPARISON OF VARIABLES THAT THE RESULTS MAY BE UN-PREDICTABLE. HOWEVER, HOW DOES ONE GET AROUND THIS SITUATION TO GET THE CORRECT RESULT DESIRED. PLEASE ADVISE, SID KRAFT   dfwlms

Joined: 04 Jan 2005
Posts: 19
Location: Huntsville, Alabama Posted: Tue Mar 24, 2015 7:22 pm    Post subject: When comparing real numbers, I always use a tolerance factor. For example: real:: numtol =1.e-12 if(x <= y+numtol)then ... With a statement such as this, and x =1.23456 and y =1.23456, the IF test above would produce the desired result, whereas the simpler statement, if(x <=y) then ... might fail because of roundoff or truncation errors in the floating point numbers._________________David Williams Retired Aerospace Engineer Huntsville, Alabama   LitusSaxonicum

Joined: 23 Aug 2005
Posts: 2208
Location: Yateley, Hants, UK Posted: Tue Mar 24, 2015 9:07 pm    Post subject: Sid, If the numbers are input values, then the test should work, but it only takes one of them to be the result of a computation, and 'Kaboom'. If you print out the logical result of each comparison, the 1 and 4 are definitely T but one of 2 or 3 is F. Probably best to do a test for plus or minus, i.e. IF (ABS(X-Y) .LE. NUMTOL) etc Eddie   JohnCampbell

Joined: 16 Feb 2006
Posts: 2277
Location: Sydney Posted: Wed Mar 25, 2015 2:49 am    Post subject: Sid,

If the number you are using is not exact in binary representation, then you will have problems, as round-off will change the result, as in the following example:

 Code: real*4    r1      real*8    d1, d2, numtol      integer*4 i      do i = 1,2 !      if (i==2) then      r1 = 1.3175      d1 = 1.3175d0      d2 = 1.3175      else      r1 = 1.5      d1 = 1.5d0      d2 = 1.5      end if      write (*,*) 'Using d2=',d2 !      if ( d1 == d2 ) write (*,*) 'd1 and d2 are the same'      if ( d1 /= d2 ) write (*,*) 'd1 and d2 are different'      write (*,*) d1-d2 !      d2 = r1      if ( d1 == d2 ) write (*,*) 'd1 and d2 are the same'      if ( d1 /= d2 ) write (*,*) 'd1 and d2 are different'      write (*,*) d1-d2 !      d2 = d1      if ( d1 == d2 ) write (*,*) 'd1 and d2 are the same'      if ( d1 /= d2 ) write (*,*) 'd1 and d2 are different'      write (*,*) d1-d2      end do !      write (*,*) 'Estimation of accuracy of d1'      numtol = abs (d1) * epsilon (d1)                         ! works if d1 /= 0      write (*,*) 'number of digits in r1 =', precision (r1)      write (*,*) 'epsilon for real*4     =', epsilon (r1)      write (*,*) 'tiny    for real*4     =', tiny (r1)      write (*,*) 'number of digits in d1 =', precision (d1)      write (*,*) 'epsilon for real*8     =', epsilon (d1)      write (*,*) 'tiny    for real*8     =', tiny (d1) !      write (*,*) 'accuracy of d1         =', numtol      write (*,*) ' useful NUMTOL test    =', 2*numtol end

However if you try r1 = 1.5 ; d1 = 1.5d0 ; d2 = 1.5 you will get a different result.
The correct way is how Eddie suggests, although it is more to code and you need to know what precision to apply to (real*8) NUMTOL.
Note: NUMTOL varies with the value of d1 (or d2 or the expected range of values for d1 or d2)
if d1 is zero, then you need a different approach for NUMTOL. Tiny(d1) is the smallest number near (not) zero, so you can see for small values of d1 you need an even smaller value for NUMTOL.

Effectively you need to say; How close to d1 is the same value ?

There is another case, where you initially give d2 the value of d1, then at the end of your routine you ask if d2 has changed. In this case if ( d1/= d2) will give the answer you want (and the compiler warnings)

John   LitusSaxonicum

Joined: 23 Aug 2005
Posts: 2208
Location: Yateley, Hants, UK Posted: Wed Mar 25, 2015 10:04 am    Post subject: John, Perfect answer. My tolerances are often a lot more physical, e.g. for a distance in km or m, to within 1mm or 5mm! Regards Eddie   Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT + 1 Hour Page 1 of 1

 Jump to: Select a forum Admin----------------Announcements FTN95----------------GeneralKBaseSupportSuggestionsClearWin+Plato64-bit FTN77----------------Support
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2001, 2005 phpBB Group