Fortran 95中的数值精度: [英] Numerical Precision in Fortran 95:
问题描述
程序奇怪
Real(Kind = 8):: Pi1 = 3.1415926535897932384626433832795028841971693993751058209;
Real(Kind = 8):: Pi2 = 3.1415926535897932384626433832795028841971693993751058209_8;
打印*,Pi1 =,Pi1;
打印*,Pi2 =,Pi2;
结束程序奇怪
我用gfortran进行编译,输出结果如下:
Pi1 = 3.1415927410125732
Pi2 = 3.1415926535897931
当然第二个是正确的,但情况应该如何?看起来Pi1正在作为一个单精度数输入到存储器中,然后放入一个双精度内存插槽。但这对我来说似乎是一个错误。我是否正确?
我知道一点Fortran! @ Dougal的回答是正确的,尽管他引用的片段不是,将字母 d
嵌入真正的文字常量中并不是必需的(因为Fortran 90),现在很多Fortran程序员认为这种做法过时了。该片段在建议使用 3.1415926535d + 0
初始化pi的64位浮点值时也存在误导,它没有将足够的数字设置为他们的正确价值。
声明:
$ b $ pre $ code真实(种类= 8):: Pi1 = 3.1415926535897932384626433832795028841971693993751058209
定义 Pi1
是一种真正的变量8.然而,字面实际值 3.1415926535897932384626433832795028841971693993751058209
是一种实际的默认值,最可能是大多数情况下为4字节的实数目前的编译器。这似乎解释你的输出,但检查你的文档。另一方面,字面上的真实值 Pi2 = 3.1415926535897932384626433832795028841971693993751058209_8
还有三点:$ b
$ b 1)不要陷入认为 kind = 8
意味着相同的陷阱例如 64位浮点数
或 double
。对于许多编译器来说,它并不是。有关数字在Fortran实现之间不可移植。根据标准,它们是任意的正整数。更好的是,使用现代编译器,将使用来自内置模块 iso_fortran_env
的预定义常量,例如
use,intrinsic :: iso_fortran_env
...
real(real64):: pi = 3.14159265358979323846264338_real64
还有其他一些使用 selected_real_kind
等函数设置变量种类的便携方法。
<2>由于
pi
的值在程序执行过程中不太可能发生变化,因此您可能需要将其设置为一个参数: real(real64),parameter :: pi = 3.14159265358979323846264338_real64
<3>除非要在源文件的同一行上有多个语句,否则不需要(或平常)用';'结束Fortran语句。
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?
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.
这篇关于Fortran 95中的数值精度:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!