- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
After reading Doctor Fortran's article on 'The Perils of Real Numbers, Part 1', Iexperimented with some old code and found the following:
REAL Sigma
CHARACTER(50) sStr
if(Sigma .GT. 6.3) RETURN
write(sStr, '(F35.30)') Sigma
..
Program did not RETURNand sStr valuewas
' 6.3000001907348632815', so Sigma was .GT. 6.3.How is it possible for Sigma.GT. 6.3 to be evaluated as .FALSE.?
Thanks for any replies.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That was Dave Eklund's article, not mine, but..
Perhaps you need to read it again. Decimal fractions are often not exactly representable in binary floating point. 6.3 is one of them. Compile and run this program and then think about your question.
write (*,'(F35.30)') 6.3
end
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Also you don't convert until after you have tested sigma. The contents of the character variable are irrelevant - you're not testing that and it has not yet affected the value of the variable you are testing.
What is the value of Sigma when you carry out the test, if its undefined you can expect erratic behaviour, somtimes it will return other times not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The number 6.3 cannot be represented using the internal storage format for floating point numbers. This is true regardless of if the number stored is REAL(4), REAL(8), REAL(16). This is due to 0.1 being an infinately long repeting binary fraction. (0.3 will also be infinately long). The internal representation can store a number that is approximately 6.3 to within one bit value of the precision of the storage format (4, 8, 16 byte) for the particular number being represented. This characteristic is similar to rounding but it would more properly be described as uncertanty.
The IF test compares the internal formats of the two numbers (or expressions) under the assumption that there is no uncertanty in the precision. Therefor, depending on how 6.3 is derived in the program you will either end up with 6.3+uncertanty or 6.3-uncertanty. Were the magnitude of the uncertanty is less than one bit of the precision of the number being represented.
To program arround this, the technique used generaly encorporates a value called epsilon. The value of epsilon is chosen such that it is larger than the largest "uncertanty" for the expected numbers to be examined with the IF statement.
Note that the value of uncertanty is different for 6.3 than for 1234.3. If you know what the value ranges are in advance, you can hard wire the epsilon. If not, then prior to the IF you can compute the epsilon, or compute a number approximately equal to your desired epsilon,using the Fortran function EPSILON(x). Where x is a variable of the same type as those to be examined in the IF test.
When you have an epsilon
if((A .gt. (Target - epsilon)) .and. (A .lt. (Target + epsilon)) call FoundA()
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One can also use:
if (abs(A-Target) < SPACING(Target)) ...
SPACING gives you the distance between the argument and the next representable value. You might want to use 2.0*SPACING to be "fuzzier". The Fortran EPSILON intrinsic is not useful for this as it always returns the spacing near 1.0.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I haven't run across such myself but I'm not exposed to such things as much as some. I'm sure that if you asked this in comp.lang.fortran you'd get some good pointers. A brief web search turns up a similarly-named article The Perils of Floating Point which I often see cited. When I was in college, I learned a lot from Volume 2 of Donald Knuth's "The Art of Computer Programming" (my favorite of the three volumes that had been published.) Perhaps others here will have additional suggestions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page