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

Relational operation - Single precision numbers

SR-9779
Beginner
1,562 Views

What's the best way to apply relational operators between two single precision (REAL(4)) numbers?

In the attached example, I am expecting "==" to be set to true.

For now, a subtraction and comparing to a very low number may work, but is there a specific guideline that needs to be followed to have these checks always return the anticipated outcomes?

 

SR9779_0-1624551326721.png

 

0 Kudos
1 Solution
mecej4
Honored Contributor III
1,497 Views

You are either unaware of, or overlooking the effect of, the fact that the internal representation/approximation of real numbers is binary, not decimal. Thus, two variables whose decimal approximations agree to seven digits may well not be identical. The indeterminism that you alluded to is simply an outcome of the irreversible destruction of information that occurs when a number has digits/bits deleted at the least significant end.

The value that you picked, 106.8582, is of such a magnitude that there are 13 different numbers in the internal representation that have the same 7-digit decimal approximation, namely,

    Z'42D5BC7F'  106.868156433

    ............

    Z'42D5BC8B'  106.858247986

The comparisons that you specify are applied to the internal representations, not to the 7-digit approximations that you see in the debugger.

You may be able to change the display format in the debugger that you are using to display more than 7 digits. You may also be able to display the numbers in hexadecimal format, which will reveal the differences.

Other responders have already suggested some sources of further information.  You may find the intrinsic functions NEAREST and EPSILON useful in this context.

Here is a small program to illustrate these observations.

program compare
real x,y
integer i
x = 106.8682
do i = -5, 5
   y = x+i*1e-5
   print 10,i,x,y,x==y
end do
10 format(i3,2F15.9,L3)
end

View solution in original post

0 Kudos
6 Replies
andrew_4619
Honored Contributor III
1,559 Views

abs(a-b) < tol, though  the value of tol depends on what the meaning of the things you are comparing. There is a small number function to give an epsilon but that is often not physically meaningful. "EPSILON(X) returns the smallest number E of the same kind as X such that 1 + E > 1."

0 Kudos
JohnNichols
Valued Contributor III
1,548 Views

There is an excellent old book, Conte and deBoore, that provides basic techniques for this type of stuff, it dates from the 70's but it is a PDF online somewhere and it gives old Fortran code. I use the book all the time as a refresher.  

0 Kudos
mecej4
Honored Contributor III
1,532 Views

"... is there a specific guideline that needs to be followed to have these checks always return the anticipated outcomes?"

What is the "anticipated outcome"? Is it unique? Answering these questions may pave the way to obtaining a workable solution.

0 Kudos
SR-9779
Beginner
1,508 Views

The anticipated outcome is that, from my OP, == returns true and all other checks return false.

 

The values of two variables (from watch window) in my OP are equal. Not sure why < returns 'true' and > returns 'false'. It could go the otherway too. Essentially, this behavior is indeterministic.

 

If I have to find a different epsilon for all the places where I use real number comparisions, it will be a lot of work. Is this something that folks out there are doing ? ie., Epsilon way to compare two real numbers? 

 

0 Kudos
mecej4
Honored Contributor III
1,498 Views

You are either unaware of, or overlooking the effect of, the fact that the internal representation/approximation of real numbers is binary, not decimal. Thus, two variables whose decimal approximations agree to seven digits may well not be identical. The indeterminism that you alluded to is simply an outcome of the irreversible destruction of information that occurs when a number has digits/bits deleted at the least significant end.

The value that you picked, 106.8582, is of such a magnitude that there are 13 different numbers in the internal representation that have the same 7-digit decimal approximation, namely,

    Z'42D5BC7F'  106.868156433

    ............

    Z'42D5BC8B'  106.858247986

The comparisons that you specify are applied to the internal representations, not to the 7-digit approximations that you see in the debugger.

You may be able to change the display format in the debugger that you are using to display more than 7 digits. You may also be able to display the numbers in hexadecimal format, which will reveal the differences.

Other responders have already suggested some sources of further information.  You may find the intrinsic functions NEAREST and EPSILON useful in this context.

Here is a small program to illustrate these observations.

program compare
real x,y
integer i
x = 106.8682
do i = -5, 5
   y = x+i*1e-5
   print 10,i,x,y,x==y
end do
10 format(i3,2F15.9,L3)
end
0 Kudos
GVautier
New Contributor II
1,479 Views

Alas, computing is not mathematics.

If the concern is about detecting as equal numbers that are "visually" equals, you can compare the decimal  representation of these numbers by writing them in strings and compare the strings.

0 Kudos
Reply