replica nfl jerseysreplica nfl jerseyssoccer jerseyreplica nfl jerseys forums.silverfrost.com :: View topic - Comparing floating point quantities for inequality
forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Comparing floating point quantities for inequality

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
eric_carwardine



Joined: 13 Jun 2009
Posts: 70
Location: Perth, Western Australia

PostPosted: Sun May 08, 2011 6:20 pm    Post subject: Comparing floating point quantities for inequality Reply with quote

G'day, folks Smile

What's a more reliable way of comparing floating point quantities for inequality? The ftn95 compiler reports that -
Code:

if( rate .ne. 0.0 ) goto 300

may give misleading results.

Eric Carwardine, in Perth, Western Australia
Back to top
View user's profile Send private message Send e-mail Visit poster's website
davidb



Joined: 17 Jul 2009
Posts: 560
Location: UK

PostPosted: Sun May 08, 2011 6:29 pm    Post subject: Re: Comparing floating point quantities for inequality Reply with quote

eric_carwardine wrote:
G'day, folks Smile

What's a more reliable way of comparing floating point quantities for inequality? The ftn95 compiler reports that -
Code:

if( rate .ne. 0.0 ) goto 300

may give misleading results.

Eric Carwardine, in Perth, Western Australia


Good morning.

Its not usually a good idea to test for equality with floating point numbers (or inequality).

The compiler is just issuing a warning. You can turn the warning off in options or use tricks like the following (and hope the compiler doesn't spot what you are doing).

Code:

   if (rate > 0.0 .or. rate < 0.0) then

      ! ... do something when rate /= 0.0

   end if


However, the effect may still give answers you don't expect.

Conventional wisdom is to do something like the following:

Code:

   if (abs(rate) > 1.0e-8) then

      ! .. do something when rate not close to zero.

   end if
Back to top
View user's profile Send private message
LitusSaxonicum



Joined: 23 Aug 2005
Posts: 2402
Location: Yateley, Hants, UK

PostPosted: Sun May 08, 2011 7:13 pm    Post subject: Reply with quote

Hi Eric,

This warning often irritates me too, particularly as I try to catch divide-by-zeroes that are the result of wrong data input (normally it hasn't been done) and not a calculation I expect to produce a "perfect" answer - I've known about roundoff for more than 4 decades, and already know that in some cases these tests aren't a good idea!

If you set a value in an assignment statement, or read a value in from a datafile, and the value is zero (or any other value for that matter), then it is perfectly proper to test for it.

e.g.

Code:
      A = 0.0
       IF (A .EQ. 0.0) THEN


You can turn off the warning for this with -ignore 179 on the command line for compilation.

The problem that FTN95 reports is that if the number is the result of a calculation, it will not be exactly calculated, and then you have to test within the range of roundoff. The accuracy you will get depends on the nature of the calculation, whether or not you use single or double precision (real*4 or real*8), how accurate the values were in the first instance, etc. If you are testing newly written code, then I advise not using the -ignore 179 option, and put up with the messages.

While programming with Clearwin I have just about given up on real*4. If find it useful to take the absolute value of the difference between two things, and compare that to the biggest difference I would consider meaningful:

Code:
      IF (DABS(A-B) .GT. ACC) THEN ... (they are different)


(Of course, in Fortran 90/95, just ABS will do). As an example, if I am surveying, then 2 points less than 0.5mm apart are considered the same, so ACC = 0.5 if my units are mm, or 0.0005 if my units are m). This is better than you can achieve with real*4. The roundoff is often a lot bigger than the "resolving power" of the datatype.

Eddie
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2615
Location: Sydney

PostPosted: Mon May 09, 2011 3:14 am    Post subject: Reply with quote

Eric,

I have tried for a while to adopt an approach which limits the warnings that FTN95 provide.
I have 2 cases where I adopt different approaches.

1) The first, where I choose to ignore the error, such as when:

A = B

{do some calculations}

if (A == B) ... ! check if A has not changed

In this case B is a special value which I have used to previously apply to A ( B can also be 0 ). I am testing if A has changed in any way. In this case I ignore the warning.
I've also asumed that "zero" is a unique real number.

2) Where the warning has some meaning, where you are testing the value of A and must recognise that real arithmetic has some finite accuracy. In this case you need to find an error "ACC" which is within limits of the calculation or within the accuracy of the method. Examples are:
1.0d-12 or 1.0e-6 may be realistic for real*8 or real*4, but also depend on the magnitude of A, as if A is expected to be 1.e-6, then a test for 1.e-16 may be more sensible for real*8 calculations.
In short it is difficult to apply a general rule for ACC.

For Eddie's example
IF (DABS(A-B) .GT. ACC) THEN
A sensible approach to ACC could be ACC = ( Abs(A) + Abs(b) ) *1.d-8,

It all depends on how frequently you do the calculation and what is the consequence of getting the test wrong. In the case of avoiding divide by zero for IF (A.NE.B) is true and if A-B is very small, and 1 / (A-B) will be very large. You need to check the consequence, which is often not a problem.

Other problems come in when ACC is set to a rounded value,
eg ACC = 0.1 .
In this case 0.1_1 is different to 0.1_2 and this can cause some other problems. Try the following code:
Code:
      real*8 x
      real*4 b, c
!
      x = 0.1_2
      b = 0.1_1
!
      c = b-x
      write (*,*) x,b,c
      end


The warning is useful to remind you to consider if it is a problem, but ignore in the case of my type 1.

John
Back to top
View user's profile Send private message
Wilfried Linder



Joined: 14 Nov 2007
Posts: 314
Location: D�sseldorf, Germany

PostPosted: Mon May 09, 2011 9:08 am    Post subject: Reply with quote

Only as an additional remark: In some cases the tiny function may be helpful which gives the smallest positive number bigger than zero. This is really near to zero, so I usually take something like r = 10.D0*tiny(1.D0) and then the expression "if (abs(x) .lt. r) ..."

Regards - Wilfried
Back to top
View user's profile Send private message
eric_carwardine



Joined: 13 Jun 2009
Posts: 70
Location: Perth, Western Australia

PostPosted: Wed Jun 01, 2011 2:21 pm    Post subject: Reply with quote

G'day, folks Smile

Crikey, it's June already! I had intended getting back here much sooner. Many thanks for all the comments!

davidb wrote:
" ... and hope the compiler doesn't spot what you are doing ... "
Almost sounds like we're dealing with HAL, David, from the film "2001: A Space Odyssey" Smile I wonder if the FTN95 compiler will ever pass the Turing Test?

Eddie wrote:
" ... While programming with Clearwin I have just about given up on real*4 ... "
I must admit, Eddie, that Clearwin's boycotting of real*4 caused me to frown a bit ... well, a lot. Then I wondered if I could get around it by using Fortran's 'internal write'. The essential code would be ...
Code:

      character output*13
      real*4 x
      ...
      write(output, 11) x
11   format(g13.6)
      ia=winio@('%`rs&', output)

... which is how I got my first demonstration of that very nice feature of Clearwin where it automatically updates any variable (such as 'output') that has been used in formatting the screen. Yes, very nice Smile

Thanks again, everybody who contributed. The overall effect of the total number of responses has lead me to ponder something I'm calling "Anatomy of a calculation", which I'll present as a separate topic.

Eric
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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