# Faithfulness of real(8) values from files

## Faithfulness of real(8) values from files

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.

10 Beiträge / 0 neu
Nähere Informationen zur Compiler-Optimierung finden Sie in unserem Optimierungshinweis.

You really want to read The Perils of Real Numbers and the subsequent articles in the later Visual Fortran Newsletter issues.

Steve

Steve

Sounds like somewhere in your code these numbers are somehow being represented as real(4). Do you have a small sample program?

James

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.

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

No, 1.2 and 1.551 are not exactly representable in REAL*8. The hex values and floating (to 17 digits) are:

```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

Steve

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

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

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

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