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

Simple compare of double Precision Floating point

Jeffrey_H_1
Beginner
1,141 Views
program test implicit none real*8 t, t_next t = 120.24d0 t_next = t - 0.04d0 write(*,*) 't=',t write(*,*) 't_next=',t_next if(t_next .eq. 120.2d0) then write(*,*) 'It works' else write(*,*) ' It doesnot work, what is the problem?' write(*,*) ' t_next inside if logic=',t_next endif stop end
0 Kudos
7 Replies
FortranFan
Honored Contributor II
1,141 Views

First, see this Dr Fortran blog: https://software.intel.com/en-us/blogs/2017/03/27/doctor-fortran-in-it-takes-all-kinds

Second, try this:

program test
   implicit none
   integer, parameter :: WP = selected_real_kind( p=15, r=307 ) ! Look into precision and range
   real(kind=WP) :: t
   real(kind=WP) :: t_next

   t = 120.24_wp
   t_next = t - 0.04_wp

   write(*,*) 't=',t
   write(*,*) 't_next=',t_next

   ! Look into EPSILON and comparison of floating-point values
   if ( abs(t_next/120.2_wp - 1.0_wp) <= epsilon(t_next) ) then
      write(*,*) 'It works'
   else
      write(*,*) ' It doesnot work, what is the problem?'
      write(*,*) ' t_next inside if logic=',t_next
   endif

   stop
end

 

0 Kudos
mecej4
Honored Contributor III
1,141 Views

Jeffrey, you seem to expect the computer to do exact decimal floating point arithmetic, since you think that 120.24 - 0.04 = 120.20. The reality, however, is that the base used in the processor for floating point is 2, not 10. In binary floating point, even a "simple" number such as 0.1 may not be represented exactly.

Dr. Fortran's article goes into this question in more detail.

0 Kudos
Jeffrey_H_1
Beginner
1,141 Views

Guys, thanks for the helps.  I am an engineer and don't know too much about the computer science.  Forgive me if I ask a stupid question.  I used this kind of checking logic often and it works until I use the Intel Parallel Studio XE 2017 Update 2 Composer Edition for Fortran Windows.  It works in my Intel 2010 version compiler.  I thought that if I declare the variables as a double precision, then it should compare two numbers up to 10 digits decimals.  I ran with a debugger and watched the number.  Although, the t_next shows exactly 120.2000000000  but still won’t go in to the correct path.  Is this to do with the new compiler?

0 Kudos
Steve_Lionel
Honored Contributor III
1,141 Views

More reading: http://software.intel.com/en-us/forums/topic/275071#comment-1548438 (Read all three parts.)

While the debugger shows 120.2 the actual infinite precision decimal value is not exactly that.

0 Kudos
FortranFan
Honored Contributor II
1,141 Views

Jeffrey Highfield wrote:

Guys, thanks for the helps.  I am an engineer and don't know too much about the computer science.  Forgive me if I ask a stupid question.  I used this kind of checking logic often and it works until I use the Intel Parallel Studio XE 2017 Update 2 Composer Edition for Fortran Windows.  It works in my Intel 2010 version compiler.  I thought that if I declare the variables as a double precision, then it should compare two numbers up to 10 digits decimals.  I ran with a debugger and watched the number.  Although, the t_next shows exactly 120.2000000000  but still won’t go in to the correct path.  Is this to do with the new compiler?

Did you try the code in Message #2?  If not, can you please try it both with your latest compiler version as well as the oldest you have i.e.,,the 2010 version?

Note you can apply your engineering background here: think of it as comparing a manufacturing product against a benchmark; you need to eliminate the random deviations in each and evaluate whether there are any systematic deviations in the product relative to the benchmark.  That is effectively what the code in Message #2 does by determining a relative error from unity and comparing it with the epsilon of the number representation. 

0 Kudos
mecej4
Honored Contributor III
1,141 Views

Jeffrey Highfield wrote:

I used this kind of checking logic often and it works until I use the Intel Parallel Studio XE 2017 Update 2 Composer Edition for Fortran Windows.  It works in my Intel 2010 version compiler.  I thought that if I declare the variables as a double precision, then it should compare two numbers up to 10 digits decimals.  I ran with a debugger and watched the number.  Although, the t_next shows exactly 120.2000000000  but still won’t go in to the correct path.  Is this to do with the new compiler?

What do you mean by "this kind of checking logic", and what is it that you wish to check?

If you watch real numbers in the debugger, you are seeing a for-human-eyes representation that is an approximation of the internal IEEE binary 64-bit representation. You can right click in the locals window in the debugger and set "hex view" to see why two numbers that agree to 10 significant decimal digits may be unequal -- equality requires that all 64-bits match.

Enter "120.42" into the online IEEE-754 emulator at http://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html and observe that there are no trailing zeros in the binary representation, although the mantissa in decimal notation is 1.8787500000000000.

0 Kudos
Jeffrey_H_1
Beginner
1,141 Views

Got it!  Thanks.

0 Kudos
Reply