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

## Simple compare of double Precision Floating point

Beginner
1,122 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
7 Replies
Honored Contributor II
1,122 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
```

Honored Contributor III
1,122 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.

Beginner
1,122 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?

Honored Contributor III
1,122 Views

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

Honored Contributor II
1,122 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.

Honored Contributor III
1,122 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.

Beginner
1,122 Views

Got it!  Thanks.