Fortran参数化派生类型组件默认值设置及精度问题问询
关于Fortran参数化派生类型的两个问题解答
一、gfortran编译错误:是疏漏还是bug?
你的代码写法完全符合Fortran标准,该编译错误是gfortran的已知bug。类似参数化派生类型组件默认值初始化时的类型推导问题,在gfortran的bug跟踪系统中已有记录。你的程序能在AOCC 4.1(flang 16.0)正常编译,也侧面印证了这一点——标准合规的代码在符合标准的编译器上可正常运行,而gfortran在此处的处理不符合标准要求。
二、如何用派生类型的kind参数指定默认值字面量类型?
在参数化派生类型中,直接使用1.0e-9_kind这类写法不被允许(因为_kind后缀要求是编译期常量,而类型参数kind是实例化时确定的值),但可以通过显式类型转换保证默认值类型与组件的kind参数一致,避免精度丢失或类型不匹配:
解决方法:显式转换默认值到参数化kind类型
修改组件定义时,用real()函数将字面量转换为当前kind对应的类型:
program test use iso_fortran_env, only: REAL32, REAL64, REAL128 implicit none type :: mytype (kind) integer, kind :: kind = REAL32 real (kind=kind) :: small = real(1.0e-9, kind=kind) ! 显式转换到参数化kind end type mytype type (mytype (kind=REAL32)) :: s type (mytype (kind=REAL64)) :: d type (mytype (kind=REAL128)) :: q end program test
这样无论实例化时使用哪种kind参数,small的默认值都会被转换为对应精度的实型,不会丢失精度;同时这种写法也能规避gfortran当前的bug限制(后续gfortran修复该bug后,写法依然完全合规)。
对于第一个程序中的matrix类型,也可采用同样方式修改small的默认值:
type :: matrix (rows, cols, kind) integer, len :: rows integer, len :: cols integer, kind :: kind = REAL32 real (kind=kind), dimension (rows, cols) :: values real (kind=kind) :: small = real(1.0e-9, kind=kind) end type matrix
内容的提问来源于stack exchange,提问作者Ghorban M. Tavakoly
相关产品推荐
相关产品推荐

