Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
This community is designed for sharing of public information. Please do not share Intel or third-party confidential information here.
27171 Discussions

Relational operation - Single precision numbers

SR-9779
Beginner
423 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
Black Belt
358 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

6 Replies
andrew_4619
Honored Contributor I
420 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."

JohnNichols
Valued Contributor II
409 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.  

mecej4
Black Belt
393 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.

SR-9779
Beginner
369 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? 

 

mecej4
Black Belt
359 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
GVautier
New Contributor II
340 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.

Reply