类型和种类#
这些内在函数允许将一种类型的变量显式转换为另一种类型,或者在处理多态变量时可用于根据变量类型有条件地执行代码块。
Fortran 数据类型#
Fortran 提供五种基本内在数据类型
- 整数类型
整数类型只能保存整数值。
- 实数类型
存储浮点数,例如 2.0、3.1415、-100.876 等。
- 复数类型
复数有两个部分,实部和虚部。两个连续的浮点存储单元存储这两个部分。
- 逻辑类型
只有两个逻辑值:.true. 和 .false.
- 字符类型
字符类型存储字符串。字符串的长度可以通过len说明符指定。如果未指定长度,则为 1。
这些“类型”可以有多种“种类”。通常,不同的数值种类占用不同的存储大小,因此可以表示不同的范围;但不同的种类可以具有其他含义。例如,字符变量可以表示 ASCII 字符、UTF-8 或 Unicode 字符。
您还可以从这些基本类型派生自己的数据类型。
隐式类型#
Fortran 允许一个称为隐式类型的特性,即您不必在使用前声明某些变量。默认情况下,如果未声明变量,则其名称的第一个字母将确定其类型
以i-n(“integer”的前两个字母)开头的变量名指定整数变量。
所有其他变量名默认为实数。
但是,在大多数情况下,声明所有变量都被认为是良好的编程实践。为了强制执行此操作,您需要使用一个语句开始您的变量声明部分,该语句关闭隐式类型:语句
implicit none
有关更多信息,请参阅implicit语句。
aimag#
名称#
aimag(3) - [类型:数值] 复数的虚部
概要#
result = aimag(z)
elemental complex(kind=KIND) function aimag(z)
complex(kind=KIND),intent(in) :: z
特性#
参数z的类型应为复数和任何支持的复数种类
返回值的类型为实数,其种类类型参数与参数相同。
描述#
aimag(3) 生成复数参数z的虚部。
这类似于现代的复数部分指示符%IM,它也指定值的虚部,接受指示符也可以出现在赋值的左侧,如val%im=10.0。
选项#
- z
要提取虚数部分的复数值。
结果#
返回值为实数值,其大小和符号与参数z的虚数部分相同。
也就是说,如果z的值为(x,y),则结果的值为y。
示例#
示例程序
program demo_aimag
use, intrinsic :: iso_fortran_env, only : real_kinds, &
& real32, real64, real128
implicit none
character(len=*),parameter :: g='(*(1x,g0))'
complex :: z4
complex(kind=real64) :: z8
! basics
z4 = cmplx(1.e0, 2.e0)
print *, 'value=',z4
print g, 'imaginary part=',aimag(z4),'or', z4%im
! other kinds other than the default may be supported
z8 = cmplx(3.e0_real64, 4.e0_real64,kind=real64)
print *, 'value=',z8
print g, 'imaginary part=',aimag(z8),'or', z8%im
! an elemental function can be passed an array
print *
print *, [z4,z4/2.0,z4+z4,z4**3]
print *
print *, aimag([z4,z4/2.0,z4+z4,z4**3])
end program demo_aimag
结果
value= (1.00000000,2.00000000)
imaginary part= 2.00000000 or 2.00000000
value= (3.0000000000000000,4.0000000000000000)
imaginary part= 4.0000000000000000 or 4.0000000000000000
(1.00000000,2.00000000) (0.500000000,1.00000000) (2.00000000,4.00000000)
(-11.0000000,-2.00000000)
2.00000000 1.00000000 4.00000000 -2.00000000
标准#
FORTRAN 77
另请参阅#
Fortran 对复数值提供了强大的支持,包括许多接受或生成复数值的内在函数,以及代数和逻辑表达式
abs(3), acosh(3), acos(3), asinh(3), asin(3), atan2(3), atanh(3), atan(3), cosh(3), cos(3), co_sum(3), dble(3), dot_product(3), exp(3), int(3), is_contiguous(3), kind(3), log(3), matmul(3), precision(3), product(3), range(3), rank(3), sinh(3), sin(3), sqrt(3), storage_size(3), sum(3), tanh(3), tan(3), unpack(3),
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
cmplx#
名称#
cmplx(3) - [类型:数值] 转换为复数类型
概要#
result = cmplx(x [,kind]) | cmplx(x [,y] [,kind])
elemental complex(kind=KIND) function cmplx( x, y, kind )
type(TYPE(kind=**)),intent(in) :: x
type(TYPE(kind=**)),intent(in),optional :: y
integer(kind=**),intent(in),optional :: KIND
特性#
x可以是整数、实数或复数。
y可以是整数或实数。仅当x不是复数时才允许使用y。
KIND是一个常数整数初始化表达式,指示结果的种类参数。
参数的类型不会影响结果的种类,除了复数x值。
如果kind不存在且x为复数,则结果为x的种类。
如果kind不存在且x不为复数,则结果为默认的复数种类。
注意:指定为**的种类可以是该类型的任何支持的种类
描述#
cmplx(3) 函数将数值转换为复数值。
即使可以使用常数使用类似于以下的语法定义复数变量
z = (1.23456789, 9.87654321)
但这对变量不起作用。因此,您无法输入
z = (a, b) ! NO ! (unless a and b are constants, not variables)
因此,要使用非复数值构造复数值,您必须使用cmplx(3) 函数
z = cmplx(a, b)
或使用%IM和%RE指示符分别为虚部和实部赋值
z%re = a
z%im = b
如果x为复数,则不允许使用y,并且cmplx基本上返回输入值,除了可选的种类更改外,这在将值传递给需要参数具有不同种类的过程(并且不返回值)时非常有用
call something(cmplx(z,kind=real64))
即使z具有不同的种类,也会传递一个种类=real64的值的副本
但在其他情况下等同于简单的赋值。因此,如果z1和z2为复数
z2 = z1 ! equivalent statements
z2 = cmplx(z1)
如果x不是复数,则x仅用于定义结果的实部,但y仍然是可选的 - 结果的虚部将被赋值为零。
如果y存在,则将其转换为虚部。
cmplx(3) 和双精度#
主要为了保持向上兼容性,在处理比默认精度更高的复数时需要小心。
Fortran 必须继续规定 cmplx(3) 在没有 kind 选项的情况下始终返回默认类型的结果,因为这是 FORTRAN 77 规定的行为。
使用参数中最高的精度来确定返回值的类型可能更好,但事实并非如此。因此,对于精度高于默认值的参数,您需要使用 kind 参数,否则更高精度的值将被降低到默认精度。
这意味着 cmplx(d1,d2),其中 d1 和 d2 为双精度,会被视为
cmplx(sngl(d1), sngl(d2))
这会导致精度损失。
因此,Fortran 90 通过添加一个额外的参数来扩展 cmplx(3) 内在函数,该参数用于指定所需的复数结果类型。
integer,parameter :: dp=kind(0.0d0)
complex(kind=dp) :: z8
! wrong ways to specify constant values
! note this was stored with default real precision !
z8 = cmplx(1.2345678901234567d0, 1.2345678901234567d0)
print *, 'NO, Z8=',z8,real(z8),aimag(z8)
z8 = cmplx(1.2345678901234567e0_dp, 1.2345678901234567e0_dp)
! again, note output components are just real
print *, 'NO, Z8=',z8,real(z8),aimag(z8)
!
! YES
!
! kind= makes it work
z8 = cmplx(1.2345678901234567d0, 1.2345678901234567d0,kind=dp)
print *, 'YES, Z8=',z8,real(z8),aimag(z8)
使用 cmplx(3) 的一个更新的替代方案是“F2018 组件语法”,其中复数实体的实部和虚部可以独立访问。
value%RE ! %RE specifies the real part
or
value%IM ! %IM specifies the imaginary part
其中设计器值当然为复数类型。
复数部分设计器的类型为实数,其类型和形状与设计器相同。也就是说,与 cmplx 不同,您默认情况下保留了复数值的精度。
以下是复数部分设计器的示例。
impedance%re !-- Same value as real(impedance)
fft%im !-- Same value as AIMAG(fft)
x%im = 0.0 !-- Sets the imaginary part of x to zero
x(1:2)%re=[10,20] !-- even if x is an array
I/O 注意#
请注意,如果指定了格式语句,则复数值将被视为两个实数值。
对于列表定向 I/O(即使用星号作为格式)和 NAMELIST 输出,预期值由“(”和“)”分隔,并采用“(实部,虚部)”的形式。对于 NAMELIST 输入,可以接受带括号的值或多个_实数_值的列表。
选项#
- x
当 x 不是复数时,分配给结果的实数组件的值。
如果 x 为复数,则结果与将输入的实部作为 x 并将虚部作为 y 传递时相同。
result = CMPLX (REAL (X), AIMAG (X), KIND).
也就是说,复数 x 值会被复制到结果值,并可能更改类型。
- y
仅当 x 不是复数时才允许使用 y。其值将分配给结果的虚数组件,如果不存在则默认为零。
- kind
一个整数初始化表达式,指示结果的类型参数。
结果#
返回值为复数类型,其大小由值 x 和 y 确定。
当 x 不是复数时的常见情况是,结果的实部被分配 x 的值,虚部为零或 y 的值(如果 y 存在)。
当 x 为复数时,不允许使用 y,结果与 x 的值相同,并可能更改类型。也就是说,实部为 real(x, kind),虚部为 real(y, kind)。
示例#
示例程序
program demo_aimag
implicit none
integer,parameter :: dp=kind(0.0d0)
real(kind=dp) :: precise
complex(kind=dp) :: z8
complex :: z4, zthree(3)
precise=1.2345678901234567d0
! basic
z4 = cmplx(-3)
print *, 'Z4=',z4
z4 = cmplx(1.23456789, 1.23456789)
print *, 'Z4=',z4
! with a format treat a complex as two real values
print '(1x,g0,1x,g0,1x,g0)','Z4=',z4
! working with higher precision values
! using kind=dp makes it keep DOUBLEPRECISION precision
! otherwise the result would be of default kind
z8 = cmplx(precise, -precise )
print *, 'lost precision Z8=',z8
z8 = cmplx(precise, -precise ,kind=dp)
print *, 'kept precision Z8=',z8
! assignment of constant values does not require cmplx(3)00
! The following is intuitive and works without calling cmplx(3)
! but does not work for variables just constants
z8 = (1.1111111111111111d0, 2.2222222222222222d0 )
print *, 'Z8 defined with constants=',z8
! what happens when you assign a complex to a real?
precise=z8
print *, 'LHS=',precise,'RHS=',z8
! elemental
zthree=cmplx([10,20,30],-1)
print *, 'zthree=',zthree
! descriptors are an alternative
zthree(1:2)%re=[100,200]
print *, 'zthree=',zthree
end program demo_aimag
结果
Z4= (-3.000000,0.0000000E+00)
Z4= (1.234568,1.234568)
Z4= 1.234568 1.234568
lost precision Z8= (1.23456788063049,-1.23456788063049)
kept precision Z8= (1.23456789012346,-1.23456789012346)
Z8 defined with constants= (1.11111111111111,2.22222222222222)
LHS= 1.11111111111111 RHS= (1.11111111111111,2.22222222222222)
zthree= (10.00000,-1.000000) (20.00000,-1.000000) (30.00000,-1.000000)
zthree= (100.0000,-1.000000) (200.0000,-1.000000) (30.00000,-1.000000)
标准#
FORTRAN 77,Fortran 90 中添加了 KIND。
另请参阅#
Fortran 对复数值提供了强大的支持,包括许多接受或生成复数值的内在函数,以及代数和逻辑表达式
abs(3), acosh(3), acos(3), asinh(3), asin(3), atan2(3), atanh(3), atan(3), cosh(3), cos(3), co_sum(3), dble(3), dot_product(3), exp(3), int(3), is_contiguous(3), kind(3), log(3), matmul(3), precision(3), product(3), range(3), rank(3), sinh(3), sin(3), sqrt(3), storage_size(3), sum(3), tanh(3), tan(3), unpack(3),
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
int#
名称#
int(3) - [类型:数值] 向零截断并转换为整数
概要#
result = int(a [,kind])
elemental integer(kind=KIND) function int(a, KIND )
TYPE(kind=**),intent(in) :: a
integer,optional :: KIND
特征#
指定为 ** 的类型可以是该类型支持的任何类型。
a 必须为整数、实数或复数类型,或为十六进制字面常量。
KIND 必须为标量整数常量表达式。
描述#
int(3) 向零截断并返回一个整数。
选项#
- a
是要向零截断的值。
- kind
指示结果的类型参数。如果不存在,则返回类型为默认整数类型。
结果#
返回一个整数变量,并应用以下规则。
情况:
如果 a 为整数类型,则 int(a) = a。
如果 a 为实数类型且 |a| < 1,int(a) 等于 0。如果 |a| >= 1,则 int(a) 等于大小不超过 a 且符号与 a 符号相同的整数。
如果 a 为复数类型,则规则 2 应用于 a 的实数部分。
如果a 为十六进制字面常量,则将其视为具有指定类型的整数。
最高有效位为 1 的位序列的解释取决于处理器。
如果无法在指定的整数类型中表示结果,则结果未定义。
示例#
示例程序
program demo_int
use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64
implicit none
integer :: i = 42
complex :: z = (-3.7, 1.0)
real :: x=-10.5, y=10.5
print *, int(x), int(y)
print *, int(i)
print *, int(z), int(z,8)
! elemental
print *, int([-10.9,-10.5,-10.3,10.3,10.5,10.9])
! note int(3) truncates towards zero
! CAUTION:
! a number bigger than a default integer can represent
! produces an incorrect result and is not required to
! be detected by the program.
x=real(huge(0))+1000.0
print *, int(x),x
! using a larger kind
print *, int(x,kind=int64),x
print *, int(&
& B"111111111111111111111111111111111111111111111111111111111111111",&
& kind=int64)
print *, int(O"777777777777777777777",kind=int64)
print *, int(Z"7FFFFFFFFFFFFFFF",kind=int64)
! elemental
print *
print *,int([ &
& -2.7, -2.5, -2.2, -2.0, -1.5, -1.0, -0.5, &
& 0.0, &
& +0.5, +1.0, +1.5, +2.0, +2.2, +2.5, +2.7 ])
end program demo_int
结果
> -10 10
> 42
> -3 -3
> -10 -10 -10 10 10 10
> -2147483648 2.14748467E+09
> 2147484672 2.14748467E+09
> 9223372036854775807
> 9223372036854775807
> 9223372036854775807
>
> -2 -2 -2 -2 -1
> -1 0 0 0 1
> 1 2 2 2 2
标准#
FORTRAN 77
另请参阅#
aint(3), anint(3), nint(3), selected_int_kind(3), ceiling(3), floor(3)
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
nint#
名称#
nint(3) - [类型:数值] 最近的整数
概要#
result = nint( a [,kind] )
elemental integer(kind=KIND) function nint(a, kind )
real(kind=**),intent(in) :: a
integer(kind=**),intent(in),optional :: KIND
特征#
指定为 ** 的类型可以是该类型支持的任何类型。
a 为任何类型的实数。
KIND 为标量整数常量表达式。
结果为默认整数类型,或者如果存在 kind,则为 kind 的值。
描述#
nint(3) 将其参数舍入到最近的整数,并保留其符号。
用户必须确保该值为返回的kind范围内的有效值。如果处理器无法在指定的类型中表示结果,则结果未定义。
如果 a 大于零,则 nint(a) 的值为 int(a+0.5)。
如果 a 小于或等于零,则 nint(a) 的值为 int(a-0.5)。
选项#
- a
要舍入到最近整数的值。
- kind
可以指定输出值的类型。如果不存在,则输出为默认整数类型。
结果#
结果为最接近 a 的整数,或者如果存在两个等距于 a 的整数,则结果为这两个整数中大小较大的那个。
如果无法在指定的整数类型中表示结果,则结果未定义。
示例#
示例程序
program demo_nint
implicit none
integer,parameter :: dp=kind(0.0d0)
real,allocatable :: in(:)
integer,allocatable :: out(:)
integer :: i
real :: x4
real(kind=dp) :: x8
! basic use
x4 = 1.234E0
x8 = 4.721_dp
print *, nint(x4), nint(-x4)
print *, nint(x8), nint(-x8)
! elemental
in = [ -2.7, -2.5, -2.2, -2.0, -1.5, -1.0, -0.5, -0.4, &
& 0.0, &
& +0.04, +0.5, +1.0, +1.5, +2.0, +2.2, +2.5, +2.7 ]
out = nint(in)
do i=1,size(in)
write(*,*)in(i),out(i)
enddo
! dusty corners
ISSUES: block
use,intrinsic :: iso_fortran_env, only : int8, int16, int32, int64
integer :: icheck
! make sure input is in range for the type returned
write(*,*)'Range limits for typical KINDS:'
write(*,'(1x,g0,1x,g0)') &
& int8,huge(0_int8), &
& int16,huge(0_int16), &
& int32,huge(0_int32), &
& int64,huge(0_int64)
! the standard does not require this to be an error ...
x8=12345.67e15 ! too big of a number
icheck=selected_int_kind(ceiling(log10(x8)))
write(*,*)'Any KIND big enough? ICHECK=',icheck
print *, 'These are all wrong answers for ',x8
print *, nint(x8,kind=int8)
print *, nint(x8,kind=int16)
print *, nint(x8,kind=int32)
print *, nint(x8,kind=int64)
endblock ISSUES
end program demo_nint
结果
> 1 -1
> 5 -5
> -2.700000 -3
> -2.500000 -3
> -2.200000 -2
> -2.000000 -2
> -1.500000 -2
> -1.000000 -1
> -0.5000000 -1
> -0.4000000 0
> 0.0000000E+00 0
> 3.9999999E-02 0
> 0.5000000 1
> 1.000000 1
> 1.500000 2
> 2.000000 2
> 2.200000 2
> 2.500000 3
> 2.700000 3
> Range limits for typical KINDS:
> 1 127
> 2 32767
> 4 2147483647
> 8 9223372036854775807
> Any KIND big enough? ICHECK= -1
> These are all wrong answers for 1.234566949990144E+019
> 0
> 0
> -2147483648
> -9223372036854775808
标准#
FORTRAN 77,带 KIND 参数 - Fortran 90。
另请参阅#
aint(3), anint(3), int(3), selected_int_kind(3), ceiling(3), floor(3)
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
real#
名称#
real(3) - [类型:数值] 转换为实数类型
概要#
result = real(x [,kind])
elemental real(kind=KIND) function real(x,KIND)
TYPE(kind=**),intent(in) :: x
integer(kind=**),intent(in),optional :: KIND
特征#
x 的类型可以是整数、实数或复数;或为十六进制字面常量。
kind 为整数初始化表达式(常量表达式)。
如果存在 kind,则它定义实数结果的类型。
如果不存在 kind
当 x 为复数时,结果为与 x 类型相同的实数。
当 x 为实数或整数时,结果为默认类型的实数。
指定为 ** 的类型可以是该类型支持的任何类型。
描述#
real(3) 将其参数 x 转换为实数类型。
返回复数值的实部。对于复数值,这类似于现代的复数部分设计器 %RE,它也指定复数值的实部。
z=(3.0,4.0) ! if z is a complex value
print *, z%re == real(z) ! these expressions are equivalent
选项#
- x
要转换为实数的整数、实数或复数值。
- kind
如果存在,则 kind 的值定义结果的类型。
结果#
如果 x 为整数或实数变量,则 real(x) 将 x 转换为默认实数类型。
real(x) 将复数值转换为实数类型,其大小为输入的实部大小,类型参数与 x 相同。
如果 x 为复数、整数或实数变量,则 real(x, kind) 将转换为类型参数为 kind 的实数类型。
示例#
示例程序
program demo_real
use,intrinsic :: iso_fortran_env, only : dp=>real64
implicit none
complex :: zr = (1.0, 2.0)
doubleprecision :: xd=huge(3.0d0)
complex(kind=dp) :: zd=cmplx(4.0e0_dp,5.0e0_dp,kind=dp)
print *, real(zr), aimag(zr)
print *, dble(zd), aimag(zd)
write(*,*)xd,real(xd,kind=kind(0.0d0)),dble(xd)
end program demo_real
结果
1.00000000 2.00000000
4.0000000000000000 5.0000000000000000
1.7976931348623157E+308 1.7976931348623157E+308 1.7976931348623157E+308
标准#
FORTRAN 77
另请参阅#
Fortran 对复数值提供了强大的支持,包括许多接受或生成复数值的内在函数,以及代数和逻辑表达式
abs(3), acosh(3), acos(3), asinh(3), asin(3), atan2(3), atanh(3), atan(3), cosh(3), cos(3), co_sum(3), dble(3), dot_product(3), exp(3), int(3), is_contiguous(3), kind(3), log(3), matmul(3), precision(3), product(3), range(3), rank(3), sinh(3), sin(3), sqrt(3), storage_size(3), sum(3), tanh(3), tan(3), unpack(3),
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
dble#
名称#
dble(3) - [类型:数值] 转换为双精度实数
概要#
result = dble(a)
elemental doubleprecision function dble(a)
doubleprecision :: dble
TYPE(kind=KIND),intent(in) :: a
特征#
a 可以是整数、实数、复数或十六进制字面常量。
结果为双精度实数。
描述#
dble(3) 将 a 转换为双精度实数类型。
选项#
- a
要转换为双精度实数的值。
结果#
返回值的类型为双精度。对于复数输入,返回值具有输入值的实部的大小和符号。
示例#
示例程序
program demo_dble
implicit none
real:: x = 2.18
integer :: i = 5
complex :: z = (2.3,1.14)
print *, dble(x), dble(i), dble(z)
end program demo_dble
结果
2.1800000667572021 5.0000000000000000 2.2999999523162842
标准#
FORTRAN 77
另请参阅#
aimag(3) - 复数的虚部
cmplx(3) - 将值转换为复数类型
int(3) - 向零截断并转换为整数
nint(3) - 最近的整数
out_of_range(3) - 值是否无法安全转换。
real(3) - 转换为实数类型
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
transfer#
名称#
transfer(3) - [TYPE:MOLD] 传输位模式
语法#
result = transfer(source, mold [,size] )
type(TYPE(kind=KIND)) function transfer(source,mold,size)
type(TYPE(kind=KIND)),intent(in) :: source(..)
type(TYPE(kind=KIND)),intent(in) :: mold(..)
integer(kind=**),intent(in),optional :: size
特征#
source 应为任何类型的标量或数组。
mold 应为任何类型的标量或数组。
size 应为整数类型的标量。
result 与mold 的类型相同
描述#
transfer(3) 将source 在内存中的位表示形式复制到与mold 类型和类型参数相同的变量或数组中。
这大致相当于 C 中将一种类型“转换”为另一种类型的概念。
选项#
- source
保存要复制的位模式
- mold
mold 的类型用于定义返回值的类型。此外,如果它是数组,则返回值为一维数组。如果它是标量,则返回值为标量。
- size
如果存在size,则结果为长度为size的一维数组。
如果size不存在,但mold 是一个数组(任何大小或形状),则结果为包含source 位表示形式全部内容所需的最小长度的一维数组。
如果size不存在且mold 是标量,则结果为标量。
结果#
结果具有source 的位级表示形式。
如果结果的位表示形式长于source 的位表示形式,则结果的前导位对应于source 的位,但任何尾随位都将任意填充。
当结果位表示形式不对应于与mold 类型相同的变量的有效表示形式时,结果未定义,并且后续对结果的操作不能保证产生合理的行为。例如,可以创建逻辑变量,其中var 和 .not. var 都似乎为真。
示例#
示例程序
program demo_transfer
use,intrinsic :: iso_fortran_env, only : int32, real32
integer(kind=int32) :: i = 2143289344
real(kind=real32) :: x
character(len=10) :: string
character(len=1) :: chars(10)
x=transfer(i, 1.0) ! prints "nan" on i686
! the bit patterns are the same
write(*,'(b0,1x,g0)')x,x ! create a NaN
write(*,'(b0,1x,g0)')i,i
! a string to an array of characters
string='abcdefghij'
chars=transfer(string,chars)
write(*,'(*("[",a,"]":,1x))')string
write(*,'(*("[",a,"]":,1x))')chars
end program demo_transfer
结果
1111111110000000000000000000000 NaN
1111111110000000000000000000000 2143289344
[abcdefghij]
[a] [b] [c] [d] [e] [f] [g] [h] [i] [j]
标准#
Fortran 90
另请参阅#
fortran-lang 内置描述
logical#
名称#
logical(3) - [TYPE:LOGICAL] 逻辑值的不同种类之间的转换
语法#
result = logical(l [,kind])
elemental logical(kind=KIND) function logical(l,KIND)
logical(kind=**),intent(in) :: l
integer(kind=**),intent(in),optional :: KIND
特征#
指定为 ** 的类型可以是该类型支持的任何类型。
l 的类型为逻辑
KIND 应为标量整数常量表达式。如果存在KIND,则结果的种类类型参数为KIND 的值指定的类型参数;否则,种类类型参数为默认逻辑的种类类型参数。
描述#
logical(3) 将一种逻辑变量转换为另一种。
选项#
- l
要生成具有种类kind 的副本的逻辑值
- kind
指示结果的种类参数。如果不存在,则返回默认种类。
结果#
返回值是一个与l 相等的逻辑值,其种类对应于kind,或者如果未给出kind 则为默认逻辑种类。
示例#
示例程序
Linux
program demo_logical
! Access array containing the kind type parameter values supported by this
! compiler for entities of logical type
use iso_fortran_env, only : logical_kinds
implicit none
integer :: i
! list kind values supported on this platform, which generally vary
! in storage size as alias declarations
do i =1, size(logical_kinds)
write(*,'(*(g0))')'integer,parameter :: boolean', &
& logical_kinds(i),'=', logical_kinds(i)
enddo
end program demo_logical
结果
> integer,parameter :: boolean1=1
> integer,parameter :: boolean2=2
> integer,parameter :: boolean4=4
> integer,parameter :: boolean8=8
> integer,parameter :: boolean16=16
标准#
Fortran 95,相关的 ISO_FORTRAN_ENV 模块 - fortran 2009
另请参阅#
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
kind#
名称#
kind(3) - [KIND:INQUIRY] 查询实体的种类
语法#
result = kind(x)
integer function kind(x)
type(TYPE,kind=**),intent(in) :: x(..)
特征#
x 可以是任何内在类型。它可以是标量或数组。
结果是默认的整数标量
描述#
kind(x)(3) 返回实体x 的种类值。
选项#
- x
要查询其种类的值。
结果#
返回值指示参数x 的种类。
请注意,种类是处理器相关的。
示例#
示例程序
program demo_kind
implicit none
integer,parameter :: dc = kind(' ')
integer,parameter :: dl = kind(.true.)
print *, "The default character kind is ", dc
print *, "The default logical kind is ", dl
end program demo_kind
结果
The default character kind is 1
The default logical kind is 4
标准#
Fortran 95
另请参阅#
allocated(3) - 可分配实体的状态
is_contiguous(3) - 测试对象是否连续
lbound(3) - 数组的下限
rank(3) - 数据对象的秩
shape(3) - 确定数组的形状
size(3) - 确定数组的大小
ubound(3) - 数组的上限
bit_size(3) - 位大小查询函数
storage_size(3) - 以位为单位的存储大小
kind(3) - 实体的种类
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
out_of_range#
名称#
out_of_range(3) - [TYPE:NUMERIC] 值是否无法安全转换。
语法#
result = out_of_range (x, mold [, round])
elemental logical function(x, mold, round)
TYPE,kind=KIND),intent(in) :: x
TYPE,kind=KIND),intent(in) :: mold
logical,intent(in),optional :: round
特征#
x 的类型为整数或实数。
mold 是整数或实数标量。
round 是逻辑标量。
结果是默认的逻辑值。
描述#
out_of_range(3) 确定值x 是否可以安全地转换为与mold 类型和种类相同的实数或整数变量。
例如,如果int8 是 8 位二进制整数类型的种类值,则out_of_range(-128.5, 0_int8) 的值为 false,而out_of_range(-128.5, 0_int8, .true.) 的值为.true.,因为在转换为整数时该值将被截断,并且 -128 即使 +128 不是,在 8 位的二进制补码机器上也是一个可表示的值。
选项#
- x
要测试的标量,以确定它是否可以存储在与mold 类型和种类相同的变量中
查询mold 和种类以确定需要适应的内容的特征。
- round
标志是否在将xx 的值验证为类似于mold 的整数之前对其进行舍入。
仅当x 的类型为实数且mold 的类型为整数时,round 才能存在。
结果#
来自标准
情况 (i):如果mold 的类型为整数,并且round 不存在或存在且值为 false,则当且仅当 X 的值为 IEEE 无穷大或 NaN,或者介于零和 X(包括)之间且具有最大幅度的整数不能由具有mold 类型和种类的对象表示时,结果为 true。
情况 (ii):如果 **mold** 的类型为整数,并且 **round** 存在且值为 true,则当且仅当 X 的值为 IEEE 无穷大或 NaN,或者 X 最近的整数(如果两个整数与 X 的距离相等,则取绝对值更大的整数)无法用类型和种类与 **mold** 相同的对象表示时,结果为真。
情况 (iii):否则,当且仅当 X 的值为 IEEE 无穷大或 NaN,且无法用类型和种类与 **mold** 相同的对象表示,或者 X 为有限数,并且根据 IEEE 舍入模式(如果适用)将 X 的值舍入到 **mold** 种类的扩展模型的结果的幅度大于可由类型和种类与 **mold** 相同的对象表示的与 X 符号相同的最大有限数的幅度时,结果为真。
注意
**mold** 必须是标量,因为从中获取的唯一信息是其类型和种类。允许数组 **mold** 将需要它与 **x** 符合。**round** 为标量,因为允许数组舍入模式将在许多处理器上造成严重的性能困难。
示例#
示例程序
program demo_out_of_range
use, intrinsic :: iso_fortran_env, only : int8, int16, int32, int64
use, intrinsic :: iso_fortran_env, only : real32, real64, real128
implicit none
integer :: i
integer(kind=int8) :: i8, j8
! compilers are not required to produce an error on out of range.
! here storing the default integers into 1-byte integers
! incorrectly can have unexpected results
do i=127,130
i8=i
j8=-i
! OUT_OF_RANGE(3f) can let you check if the value will fit
write(*,*)i8,j8,' might have expected',i,-i, &
& out_of_range( i,i8), &
& out_of_range(-i,i8)
enddo
write(*,*) 'RANGE IS ',-1-huge(0_int8),'TO',huge(0_int8)
! the real -128.5 is truncated to -128 and is in range
write(*,*) out_of_range ( -128.5, 0_int8) ! false
! the real -128.5 is rounded to -129 and is not in range
write(*,*) out_of_range ( -128.5, 0_int8, .true.) ! true
end program demo_out_of_range
结果
> 127 -127 might have expected 127 -127 F F
> -128 -128 might have expected 128 -128 T F
> -127 127 might have expected 129 -129 T T
> -126 126 might have expected 130 -130 T T
> RANGE IS -128 TO 127
> F
> T
标准#
FORTRAN 2018
另请参阅#
aimag(3) - 复数的虚部
cmplx(3) - 将值转换为复数类型
dble(3) - 双精度转换函数
int(3) - 向零截断并转换为整数
nint(3) - 最近的整数
real(3) - 转换为实数类型
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
selected_char_kind#
名称#
selected_char_kind(3) - [KIND] 选择字符种类,例如“Unicode”
概要#
result = selected_char_kind(name)
integer function selected_char_kind(name)
character(len=*),intent(in) :: name
特征#
name 是一个默认的 字符 标量
结果是默认的整数标量
描述#
selected_char_kind(3) 返回名为 **name** 的字符集的种类参数值。
如果名称不受支持,则返回 -1。否则,结果等于该种类类型参数值。
支持的名称列表取决于处理器,但“DEFAULT”除外。
如果 **name** 的值为“DEFAULT”,则结果的值等于默认字符的种类类型参数的值。此名称始终受支持。
如果 **name** 的值为“ASCII”,则结果的值等于 ASCII 字符的种类类型参数的值。
如果 **name** 的值为“ISO_10646”,则结果的值等于 ISO 10646 字符种类的种类类型参数的值(对应于 ISO/IEC 10646 中指定的 UCS-4)。
如果 **name** 是处理器定义的某种其他字符种类的名称,并且处理器支持该字符种类,则结果的值等于该种类类型参数值。预定义的名称包括“ASCII”和“ISO_10646”。
NAME 的解释不区分大小写,也不考虑尾随空格。
选项#
- name
要查询处理器相关的种类值的名称,以及/或者确定是否受支持。**name**,其解释不区分大小写,也不考虑尾随空格。
目前,支持的字符集包括“ASCII”和“DEFAULT”以及“ISO_10646”(通用字符集,UCS-4),通常称为“Unicode”。除“DEFAULT”之外的支持名称取决于处理器。
结果#
示例#
示例程序
Linux
program demo_selected_char_kind
use iso_fortran_env
implicit none
intrinsic date_and_time,selected_char_kind
! set some aliases for common character kinds
! as the numbers can vary from platform to platform
integer, parameter :: default = selected_char_kind ("default")
integer, parameter :: ascii = selected_char_kind ("ascii")
integer, parameter :: ucs4 = selected_char_kind ('ISO_10646')
integer, parameter :: utf8 = selected_char_kind ('utf-8')
! assuming ASCII and UCS4 are supported (ie. not equal to -1)
! define some string variables
character(len=26, kind=ascii ) :: alphabet
character(len=30, kind=ucs4 ) :: hello_world
character(len=30, kind=ucs4 ) :: string
write(*,*)'ASCII ',&
& merge('Supported ','Not Supported',ascii /= -1)
write(*,*)'ISO_10646 ',&
& merge('Supported ','Not Supported',ucs4 /= -1)
write(*,*)'UTF-8 ',&
& merge('Supported ','Not Supported',utf8 /= -1)
if(default.eq.ascii)then
write(*,*)'ASCII is the default on this processor'
endif
! for constants the kind precedes the value, somewhat like a
! BOZ constant
alphabet = ascii_"abcdefghijklmnopqrstuvwxyz"
write (*,*) alphabet
hello_world = ucs4_'Hello World and Ni Hao -- ' &
// char (int (z'4F60'), ucs4) &
// char (int (z'597D'), ucs4)
! an encoding option is required on OPEN for non-default I/O
if(ucs4 /= -1 )then
open (output_unit, encoding='UTF-8')
write (*,*) trim (hello_world)
else
write (*,*) 'cannot use utf-8'
endif
call create_date_string(string)
write (*,*) trim (string)
contains
! The following produces a Japanese date stamp.
subroutine create_date_string(string)
intrinsic date_and_time,selected_char_kind
integer,parameter :: ucs4 = selected_char_kind("ISO_10646")
character(len=1,kind=ucs4),parameter :: &
nen = char(int( z'5e74' ),ucs4), & ! year
gatsu = char(int( z'6708' ),ucs4), & ! month
nichi = char(int( z'65e5' ),ucs4) ! day
character(len= *, kind= ucs4) string
integer values(8)
call date_and_time(values=values)
write(string,101) values(1),nen,values(2),gatsu,values(3),nichi
101 format(*(i0,a))
end subroutine create_date_string
end program demo_selected_char_kind
结果
结果在很大程度上取决于处理器
> ASCII Supported
> ISO_10646 Supported
> UTF-8 Not Supported
> ASCII is the default on this processor
> abcdefghijklmnopqrstuvwxyz
> Hello World and Ni Hao -- 你好
> 2022年10月15日
标准#
Fortran 2003
另请参阅#
selected_int_kind(3),selected_real_kind(3)
achar(3),char(3),ichar(3),iachar(3)
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
selected_int_kind#
名称#
selected_int_kind(3) - [KIND] 选择整数种类
概要#
result = selected_int_kind(r)
integer function selected_int_kind(r)
integer(kind=KIND),intent(in) :: r
特征#
r 是一个 整数 标量。
结果是一个默认的整数标量。
描述#
selected_int_kind(3) 返回可以表示从 -10**r(不包括)到 10**r(不包括)的所有值的最小整数类型的种类值。如果不存在可以容纳此范围的整数种类,则 selected_int_kind 返回 -1。
选项#
- r
该值指定需要由返回的种类类型支持的十的幂范围。
结果#
结果的值等于表示请求范围内所有值的整数类型的种类类型参数的值。
如果处理器上不存在此类种类类型参数,则结果为 -1。
如果多个种类类型参数满足条件,则返回十进制指数范围最小的那个,除非存在多个这样的值,在这种情况下,返回这些种类值中最小的那个。
示例#
示例程序
program demo_selected_int_kind
implicit none
integer,parameter :: k5 = selected_int_kind(5)
integer,parameter :: k15 = selected_int_kind(15)
integer(kind=k5) :: i5
integer(kind=k15) :: i15
print *, huge(i5), huge(i15)
! the following inequalities are always true
print *, huge(i5) >= 10_k5**5-1
print *, huge(i15) >= 10_k15**15-1
end program demo_selected_int_kind
结果
> 2147483647 9223372036854775807
> T
> T
标准#
Fortran 95
另请参阅#
aint(3),anint(3),int(3),nint(3),ceiling(3),floor(3)
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
selected_real_kind#
名称#
selected_real_kind(3) - [KIND] 选择实数种类
概要#
result = selected_real_kind([p] [,r] [,radix] )
integer function selected_int_kind(r)
real(kind=KIND),intent(in),optional :: p
real(kind=KIND),intent(in),optional :: r
real(kind=KIND),intent(in),optional :: radix
特征#
p 是一个 整数 标量
r 是一个 整数 标量
radix 是一个 整数 标量
结果是一个默认的 整数 标量
描述#
selected_real_kind(3) 返回具有至少 **p** 位十进制精度、至少 **r** 的指数范围以及 **radix** 基数的 实数 数据类型的种类值。也就是说,如果存在这样的种类
+ it has the decimal precision as returned by **precision**(3) of at
least **p** digits.
+ a decimal exponent range, as returned by the function **range**(3)
of at least **r**
+ a radix, as returned by the function **radix**(3) , of **radix**,
如果请求的种类不存在,则返回 -1。
至少应存在一个参数。
选项#
- p
请求的精度
- r
请求的范围
- radix
所需的基数
在 **Fortran 2008** 之前,至少应存在参数 **r** 或 **p** 中的一个;自 **Fortran 2008** 起,如果不存在,则假定它们为零。
结果#
selected_real_kind 返回具有至少 **p** 位十进制精度、至少 R 的十进制指数范围以及请求的 **radix** 的实数数据类型的种类类型参数的值。
如果 **p** 或 **r** 不存在,则结果值与它们存在且值为零时相同。
如果 **radix** 参数不存在,则对所选种类的基数没有要求,并且可以返回任何基数的实数种类。
如果多个实数数据类型满足条件,则返回十进制精度最小的数据类型的种类。如果没有任何实数数据类型匹配条件,则结果为
- -1
如果处理器不支持精度大于或等于 **p** 的实数数据类型,但可以满足 **r** 和 **radix** 要求
- -2
如果处理器不支持指数范围大于或等于 **r** 的实数类型,但可以满足 **p** 和 **radix** 要求
- -3
如果可以满足 **radix** 要求,但不能满足 **p** 和 **r** 要求
- -4
如果可以满足 **radix** 要求以及 **p** 或 **r** 要求中的一个
- -5
如果不存在具有给定 **radix** 的实数类型
示例#
示例程序
program demo_selected_real_kind
implicit none
integer,parameter :: p6 = selected_real_kind(6)
integer,parameter :: p10r100 = selected_real_kind(10,100)
integer,parameter :: r400 = selected_real_kind(r=400)
real(kind=p6) :: x
real(kind=p10r100) :: y
real(kind=r400) :: z
print *, precision(x), range(x)
print *, precision(y), range(y)
print *, precision(z), range(z)
end program demo_selected_real_kind
结果
> 6 37
> 15 307
> 18 4931
标准#
Fortran 95;带 RADIX - Fortran 2008
另请参阅#
precision(3),range(3),radix(3)
fortran-lang 内在函数描述(许可证:MIT)@urbanjost
注释#
Joe Krahn:Fortran 使用造型而不是转换。
转换,如 C 中一样,是就地重新解释。转换是围绕对象构建的用于更改其形状的设备。
Fortran transfer(3) 重新解释异地数据。它可以被认为是造型而不是转换。模具是一种将形状赋予放置在其上的对象的设备。
造型的优点是数据在持有它的变量的上下文中始终有效。对于许多情况,一个不错的编译器应该将transfer(3) 优化为简单的赋值。
这种方法有一些缺点。定义数据类型的联合存在问题,因为您必须知道最大的数据对象,这可能因编译器或编译选项而异。在许多情况下,EQUIVALENCE 会更有效,但 Fortran 标准委员会似乎忽略了在谨慎使用时EQUIVALENCE 的好处。