我有以下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作为单个精度数字输入到内存,然后放入双精度内存插槽。但这对我来说似乎是一个错误。我是对的吗?
答案 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=8
与64-bit floating-point number
或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语句除非你想在源文件的同一行上有多个语句。
答案 1 :(得分:3)
我真的不知道Fortran,但this page说:
字母“d”必须嵌入文字中,否则,编译器的预处理器会将其四舍五入为Single Precision文字。例如,3.1415926535将被读取为3.141593,而3.1415926535d + 0将被存储,所有数字都保持不变。双精度数字的字母“d”与单精度数字的“e”含义相同。
所以看起来你的猜测是正确的。