- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am using CVF 6.5.A on Windows 2000 / Pentium III.
I read numbers from a text file into real(8) variables, and then I print these variables.
Numbers like 1.625, 6.5 come out as 1.625000, 6.500000.
But numbers like 1.2, 1.551 come out as 1.199999, 1.550999.
What is going on? Solutions?
There seems to be a pattern, which may or may not be true: numbers appear to be faithfully carried by real(8) variables when the only prime divisor of the decimal part is 5.
I read numbers from a text file into real(8) variables, and then I print these variables.
Numbers like 1.625, 6.5 come out as 1.625000, 6.500000.
But numbers like 1.2, 1.551 come out as 1.199999, 1.550999.
What is going on? Solutions?
There seems to be a pattern, which may or may not be true: numbers appear to be faithfully carried by real(8) variables when the only prime divisor of the decimal part is 5.
Link Copied
9 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You really want to read The Perils of Real Numbers and the subsequent articles in the later Visual Fortran Newsletter issues.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sounds like somewhere in your code these numbers are somehow being represented as real(4). Do you have a small sample program?
James
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you for your response. I actually do not have any real(4) variables. The article that Steve Lionel suggested is very interesting. I have not finished reading it yet but I think it explains what I saw.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The article explains how floating point numbers are stored, but does not explain the lack of precision you were seeing. From the numbers that you posted, you are either explicitly or implicitly using a real(4) somewhere between reading the file and when you display them. A real(8) should be able to hold those particular numbers properly.
James
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
No, 1.2 and 1.551 are not exactly representable in REAL*8. The hex values and floating (to 17 digits) are:
The point to remember is that computers (all that we care about, anyway) store floating point numbers with base-2 fractions, and that many decimal fractions do not have exact representations in binary floating point.
Steve
3FF3333333333333 1.19999999999999996 3FF8D0E560418937 1.55099999999999993
The point to remember is that computers (all that we care about, anyway) store floating point numbers with base-2 fractions, and that many decimal fractions do not have exact representations in binary floating point.
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
I never said they were exactly representable. To the number of digits being displayed in the original question, they are accurately represented, with the seven significant digits being used. Usually what people are confused by is when the typical formatting shows a "different" number than they began with.
With double precision these numbers are correctly represented out to far more than 7 digits, as you describe in your reply, and the fact that the original question included the quantities "1.199999" and "1.550999" tells me that somewhere they are possibly being represented in single precision. Otherwise they would be the expected 1.200000 and 1.551000 using real(8) and 7 significant digits, and the question likely would have not been asked.
James
I never said they were exactly representable. To the number of digits being displayed in the original question, they are accurately represented, with the seven significant digits being used. Usually what people are confused by is when the typical formatting shows a "different" number than they began with.
With double precision these numbers are correctly represented out to far more than 7 digits, as you describe in your reply, and the fact that the original question included the quantities "1.199999" and "1.550999" tells me that somewhere they are possibly being represented in single precision. Otherwise they would be the expected 1.200000 and 1.551000 using real(8) and 7 significant digits, and the question likely would have not been asked.
James
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We don't know how the values actually appeared - he may have typed in only the first few digits. I agree that if these values were displayed to ONLY that number of digits, then they should have shown as rounded up to the desired values.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I indeed displayed only the first few digits in my posting.
And this issue is indeed only about understanding how
real numbers are represented. Even the fact that my numbers
came from a file is irrelevant.
Here is a small test program:
program real8
implicit none
real(8) number(1:4)
number(1) = 1.625_8
number(2) = 6.5_8
number(3) = 1.2_8
number(4) = 1.551_8
write(6, '(4(f44.40,/))') number
end program real8
And here is its output:
1.6250000000000000000000000000000000000000
6.5000000000000000000000000000000000000000
1.1999999999999999555910790149937383830000
1.5509999999999999342747969421907328070000
And this issue is indeed only about understanding how
real numbers are represented. Even the fact that my numbers
came from a file is irrelevant.
Here is a small test program:
program real8
implicit none
real(8) number(1:4)
number(1) = 1.625_8
number(2) = 6.5_8
number(3) = 1.2_8
number(4) = 1.551_8
write(6, '(4(f44.40,/))') number
end program real8
And here is its output:
1.6250000000000000000000000000000000000000
6.5000000000000000000000000000000000000000
1.1999999999999999555910790149937383830000
1.5509999999999999342747969421907328070000
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the clarification... Your mention of reading from a file, then the fact that all the numbers were seven digits made me suspicious. I've see a lot of people not understand situations like the following, which is why I asked:
real(8) x
x = 1.2
print *, x
x = 1.2_8
print *, x
end
results:
1.20000004768372
1.20000000000000
The moral of floating point is don't use it if you want absolute truth, however with enough precision (and understanding) it does what most people want. Otherwise you need COBOL. :-)
James
real(8) x
x = 1.2
print *, x
x = 1.2_8
print *, x
end
results:
1.20000004768372
1.20000000000000
The moral of floating point is don't use it if you want absolute truth, however with enough precision (and understanding) it does what most people want. Otherwise you need COBOL. :-)
James

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