Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
327 views
in Technique[技术] by (71.8m points)

gfortran - Numerical Precision in Fortran 95:

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...