关于FORTRAN中种类的混淆

时间:2015-05-04 07:05:20

标签: fortran precision hdf5 double-precision

我已经在为一个应用物理问题的数值模拟编写FORTRAN代码两年多了,我试图遵循Fortran Best Practices中描述的约定。

更具体地说,我将参数定义为

integer, parameter:: dp=kind(0.d0)

然后将其用于我的代码中的所有双打。

但是,我发现(在这个论坛上)如果使用其他编译器编译代码,使用KIND参数不一定能提供相同的精度。在this question中,我读到一个可能的解决方案是使用SELECTED_REAL_KIND和SELECTED_INT_KIND,这符合一些约定,据我所知。

稍后,我发现了ISO_FORTRAN_ENV模块,该模块定义了REAL32,REAL64和REAL128 KIND参数。

我猜这些确实是可移植的,因为它们属于FORTRAN 2008标准(虽然受GNU支持),我想我应该使用它们吗?

因此,如果有更多知识和经验的人能够消除困惑,我将不胜感激。

另外,我有一个关于在HDF5中使用这些KIND的后续问题。我正在使用H5T_NATIVE_DOUBLE,它确实工作正常(据我所知)但是,in this document声明这是一个过时的功能,不应该使用。相反,它们提供了一种功能

INTEGER(HID_T) FUNCTION h5kind_to_type(kind, flag) RESULT(h5_type) . 

当我使用它时,打印出对应于REAL64的HID_T整数的确切数值给出了50331972,而H5T_NATIVE_DOUBLE给了我50331963,这是不同的。

如果我然后尝试使用H5kind_to_type计算的值,HDF5库运行得很好,使用XDMF,我可以在VisIt或Paraview中绘制输出,而无需修改附带的.xmf文件。

所以我的第二个问题是(再次):这是正确的用法吗?

1 个答案:

答案 0 :(得分:6)

类型double precision和相应类型kind(1.d0)完全由标准定义。但它们也没有完全修复。事实上,历史上有许多计算机,并使用不同类型的原生格式作为浮点数,标准必须允许这样!

因此,double precision是一种real,其精度高于默认real。默认的实际也不是固定的,它必须与计算机可以使用的内容相对应。

现在我们有了浮点数IEEE_754的标准,它定义了IEEE单(binary32)和IEEE双类(binary64)以及其他一些。如果计算机硬件实现了这个标准,就像几乎所有20年以下的计算机一样,编译器很可能选择这两个作为realdouble precision

Fortran 2008标准带来了两种常量real32real64(以及其他常量)。它们使您能够请求存储大小为32位和64位的实际类型。它不能保证它是IEEE类型,但在现代计算机上几乎可以肯定。

要请求IEEE类型(如果可用),请使用模块ieee_selected_real_kind()中的内部函数ieee_arithmetic

IEEE类型与所有计算机相同(不包括字节序!),但编译器不需要支持它们,因为您可能有一台计算机在硬件中不支持这些。这只是理论上的可能性,所有现代计算机都支持它们。

现在对于你的HDF常数,这些显然只是某些表的某些索引,无论它们是否不同都没关系,重要的是它们是否意味着相同而且在你的情况下它们是这样。

正如我上面所写,在支持IEEE 754的计算机上,double precision极有可能与IEEE double相同。如果您使用某些更改此行为的编译器选项,则可能不是。有一些编译器选项可以将默认real提升到两倍,并且hey也可以将double precision提升为四倍精度(128位)以保留标准语义,这需要double precision具有更高的精度和存储大小。

结论:您可以使用这两种方式或任何其他方式来选择您的种类常量(您也可以使用iso_c_binding的{​​{1}}和c_float) ,但你应该知道为什么这些方式不同,它们实际意味着什么。