- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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."
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"... 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page