6

I have the following Fortran code:

Program Strange
   Real(Kind=8)::Pi1=3.1415926535897932384626433832795028841971693993751058209;
   Real(Kind=8)::Pi2=3.1415926535897932384626433832795028841971693993751058209_8;

   Print*, "Pi1=", Pi1;
   Print*, "Pi2=", Pi2;

End Program Strange

I compile with gfortran, and the output is:

 Pi1=   3.1415927410125732     
 Pi2=   3.1415926535897931

Of course the second is correct, but should this be the case? It seems like Pi1 is being input to memory as a single precision number, and then put into a double precision memory slot. But this seems like an error to me. Am I correct?

4

2 回答 2

10

I do know a bit of Fortran ! @Dougal's answer is correct though the snippet he quotes from is not, embedding the letter d into a real literal constant is not required (since Fortran 90), indeed many Fortran programmers now regard that approach as archaic. The snippet is also misleading in advising the use of 3.1415926535d+0 to initialise a 64-bit floating-point value for pi, it doesn't set enough of the digits to their correct values.

The statement:

Real(Kind=8)::Pi1=3.1415926535897932384626433832795028841971693993751058209

defines Pi1 to be a real variable of kind 8. The literal real value 3.1415926535897932384626433832795028841971693993751058209 is, however, a real value of default kind, most likely to be a 4-byte real on most current compilers. That seems to explain your output but do check your documentation.

On the other hand, the literal real value Pi2=3.1415926535897932384626433832795028841971693993751058209_8 is, by the suffixing of the kind specification, declared to be of kind=8 which is the same as the kind of the variable it is assigned to.

Three more points:

1) Don't fall into the trap of thinking that kind=8 means the same thing as 64-bit floating-point number or double. For many compilers it does, for some it doesn't. Kind numbers are not portable between Fortran implementations. They are, according to the standard, arbitrary positive integers. Better, with a modern compiler, would be to use the predefined constants from the intrinsic module iso_fortran_env, e.g.

use, intrinsic :: iso_fortran_env
...
real(real64) :: pi = 3.14159265358979323846264338_real64

There are other portable approaches to setting variable kinds using functions such as selected_real_kind.

2) Since the value of pi is unlikely to change during the execution of your program you might care to make it a parameter thus:

real(real64), parameter :: pi = 3.14159265358979323846264338_real64

3) It isn't necessary (or usual) to end Fortran statements with a ';' unless you want to have more than one statement on the same line in the source file.

于 2013-05-04T10:15:11.460 回答
3

I don't really know Fortran, but this page says:

The letter "d" must be embedded in the literal, otherwise, the compiler's pre-processor would round it off to be a Single Precision literal. For example, 3.1415926535 would be read as 3.141593 while 3.1415926535d+0 would be stored with all the digits intact. The letter "d" for double precision numbers has the same meaning as "e" for single precision numbers.

So it seems like your guess is correct.

于 2013-05-04T03:16:20.633 回答