Fortran 95中的数值精度:

时间:2013-05-04 03:11:23

标签: fortran gfortran fortran95 numerical-analysis

我有以下Fortran代码:

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

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

End Program Strange

我用gfortran编译,输出是:

 Pi1=   3.1415927410125732     
 Pi2=   3.1415926535897931

当然第二个是正确的,但是应该是这样吗?似乎Pi1作为单个精度数字输入到内存,然后放入双精度内存插槽。但这对我来说似乎是一个错误。我是对的吗?

2 个答案:

答案 0 :(得分:10)

我确实知道一点Fortran! @ Dougal的答案是正确的,虽然他引用的片段不是,将字母d嵌入到真正的文字常量中是不必要的(因为Fortran 90),实际上许多Fortran程序员现在认为这种方法是过时的。该片段在建议使用3.1415926535d+0初始化pi的64位浮点值时也会产生误导,它没有将足够的数字设置为正确的值。

声明:

Real(Kind=8)::Pi1=3.1415926535897932384626433832795028841971693993751058209

Pi1定义为类型8的实数变量。然而,字面实数值3.1415926535897932384626433832795028841971693993751058209是默认类型的实际值,最有可能是大多数当前的4字节实数编译器。这似乎可以解释您的输出,但请检查您的文档。

另一方面,通过类型规范的后缀,字面实数值Pi2=3.1415926535897932384626433832795028841971693993751058209_8被声明为kind = 8,它与分配给它的变量的种类相同。 / p>

还有三点:

1)不要陷入认为kind=864-bit floating-point numberdouble相同的陷阱。对于许多编译器来说,它确实如此,但有些编译器没有。 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语句除非你想在源文件的同一行上有多个语句。

答案 1 :(得分:3)

我真的不知道Fortran,但this page说:

  

字母“d”必须嵌入文字中,否则,编译器的预处理器会将其四舍五入为Single Precision文字。例如,3.1415926535将被读取为3.141593,而3.1415926535d + 0将被存储,所有数字都保持不变。双精度数字的字母“d”与单精度数字的“e”含义相同。

所以看起来你的猜测是正确的。