现代 Fortran 中的整数精度
Integer precision in modern Fortran
selected_int_kind(int16)
的值显示为 1 而不是 2。这是编译器错误吗?
在以下输出中,请注意 bint
的差异,本意为 2 个字节,INT16
。 (为清楚起见,添加了注释 <===。)
compiler version = GCC version 5.1.0
compiler options = -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -Og -Wall -Wextra -Wconversion -Wpedantic -fcheck=bounds -fmax-errors=5
execution command = ./a.out
Number of bytes in type default = 4
Number of bytes in type int_8 = 1
Number of bytes in type int_16 = 2 <===
Number of bytes in type int_32 = 4
Number of bytes in type int_64 = 8
Number of bytes in type int_a = 1
Number of bytes in type int_b = 1 <===
Number of bytes in type int_c = 2
Number of bytes in type int_d = 4
Value of aint = 1
Value of bint = 1 <===
Value of cint = 2
Value of dint = 4
Value of selected_int_kind ( INT16 ) = 1 <===
以下代码供读者研究此问题。有问题的作业在第 13 行。
program bytes
use iso_fortran_env
implicit NONE
integer :: default
integer ( int8 ) :: int_8
integer ( int16 ) :: int_16
integer ( int32 ) :: int_32
integer ( int64 ) :: int_64
integer, parameter :: aint = selected_int_kind ( INT8 )
integer, parameter :: bint = selected_int_kind ( INT16 )
integer, parameter :: cint = selected_int_kind ( INT32 )
integer, parameter :: dint = selected_int_kind ( INT64 )
integer ( aint ) :: int_a
integer ( bint ) :: int_b
integer ( cint ) :: int_c
integer ( dint ) :: int_d
character ( len = * ), parameter :: c_options = compiler_options( )
character ( len = * ), parameter :: c_version = compiler_version( )
character ( len = 255 ) :: cmd = " "
call get_command ( cmd )
write ( *, '( "compiler version = ", g0 )' ) c_version
write ( *, '( "compiler options = ", g0 )' ) trim ( c_options )
write ( *, '( "execution command = ", g0, / )' ) trim ( cmd )
write ( * , 100 ) 'default', sizeof ( default )
write ( * , 100 ) 'int_8', sizeof ( int_8 )
write ( * , 100 ) 'int_16', sizeof ( int_16 )
write ( * , 100 ) 'int_32', sizeof ( int_32 )
write ( * , 100 ) 'int_64', sizeof ( int_64 )
write ( * , 100 ) 'int_a', sizeof ( int_a )
write ( * , 100 ) 'int_b', sizeof ( int_b )
write ( * , 100 ) 'int_c', sizeof ( int_c )
write ( * , 100 ) 'int_d', sizeof ( int_d )
write ( * , 110 ) 'aint', aint
write ( * , 110 ) 'bint', bint
write ( * , 110 ) 'cint', cint
write ( * , 110 ) 'dint', dint
write ( * , 110 ) 'selected_int_kind ( INT16 )', selected_int_kind ( INT16 )
100 format ( "Number of bytes in type ", g0, " = ", g0 )
110 format ( "Value of ", g0, " = ", g0 )
end program bytes
这不是错误。标准(Fortran 95 13.14.94、Fortran 2003 13.7.105 和 Fortran 2008 13.7.146)对 selected_int_kind(R)
有这样的说法:
Argument. R shall be an integer scalar.
Result Value. The result has a value equal to the value of the kind type parameter of an integer type that represents all values n in the range −10R < n < 10R, or if no such kind type parameter is available on the processor, the result is −1. If more than one kind type parameter meets the criterion, the value returned is the one with the smallest decimal exponent range, unless there are several such values, in which case the smallest of these kind values is returned.
这意味着,如果 int16
在您的平台上恰好是 2
,则 selected_int_kind(2)
将 return 能够表示范围的最小整数类型 - 100到+100,是一个存储大小为1的单字节,所以int8
的值为returned.
下面一个简单程序的输出应该演示它是如何工作的:
Value of int8 1
Value of int16 2
Value of int32 4
Value of int64 8
Value of selected_int_kind(1) 1
Value of selected_int_kind(2) 1
Value of selected_int_kind(3) 2
Value of selected_int_kind(4) 2
Value of selected_int_kind(5) 4
Value of selected_int_kind(6) 4
Value of selected_int_kind(7) 4
Value of selected_int_kind(8) 4
Value of selected_int_kind(9) 4
Value of selected_int_kind(10) 8
Value of selected_int_kind(11) 8
Value of selected_int_kind(12) 8
Value of selected_int_kind(13) 8
Value of selected_int_kind(14) 8
Value of selected_int_kind(15) 8
Value of selected_int_kind(16) 8
Value of selected_int_kind(17) 8
Value of selected_int_kind(18) 8
Value of selected_int_kind(19) 16
Value of selected_int_kind(20) 16
Value of selected_int_kind(21) 16
Value of selected_int_kind(22) 16
This file was compiled by GCC version 5.2.0 using the options -mtune=generic -march=x86-64 -std=f2008
selected_int_kind(int16)
的值显示为 1 而不是 2。这是编译器错误吗?
在以下输出中,请注意 bint
的差异,本意为 2 个字节,INT16
。 (为清楚起见,添加了注释 <===。)
compiler version = GCC version 5.1.0
compiler options = -fPIC -mmacosx-version-min=10.9.4 -mtune=core2 -Og -Wall -Wextra -Wconversion -Wpedantic -fcheck=bounds -fmax-errors=5
execution command = ./a.out
Number of bytes in type default = 4
Number of bytes in type int_8 = 1
Number of bytes in type int_16 = 2 <===
Number of bytes in type int_32 = 4
Number of bytes in type int_64 = 8
Number of bytes in type int_a = 1
Number of bytes in type int_b = 1 <===
Number of bytes in type int_c = 2
Number of bytes in type int_d = 4
Value of aint = 1
Value of bint = 1 <===
Value of cint = 2
Value of dint = 4
Value of selected_int_kind ( INT16 ) = 1 <===
以下代码供读者研究此问题。有问题的作业在第 13 行。
program bytes
use iso_fortran_env
implicit NONE
integer :: default
integer ( int8 ) :: int_8
integer ( int16 ) :: int_16
integer ( int32 ) :: int_32
integer ( int64 ) :: int_64
integer, parameter :: aint = selected_int_kind ( INT8 )
integer, parameter :: bint = selected_int_kind ( INT16 )
integer, parameter :: cint = selected_int_kind ( INT32 )
integer, parameter :: dint = selected_int_kind ( INT64 )
integer ( aint ) :: int_a
integer ( bint ) :: int_b
integer ( cint ) :: int_c
integer ( dint ) :: int_d
character ( len = * ), parameter :: c_options = compiler_options( )
character ( len = * ), parameter :: c_version = compiler_version( )
character ( len = 255 ) :: cmd = " "
call get_command ( cmd )
write ( *, '( "compiler version = ", g0 )' ) c_version
write ( *, '( "compiler options = ", g0 )' ) trim ( c_options )
write ( *, '( "execution command = ", g0, / )' ) trim ( cmd )
write ( * , 100 ) 'default', sizeof ( default )
write ( * , 100 ) 'int_8', sizeof ( int_8 )
write ( * , 100 ) 'int_16', sizeof ( int_16 )
write ( * , 100 ) 'int_32', sizeof ( int_32 )
write ( * , 100 ) 'int_64', sizeof ( int_64 )
write ( * , 100 ) 'int_a', sizeof ( int_a )
write ( * , 100 ) 'int_b', sizeof ( int_b )
write ( * , 100 ) 'int_c', sizeof ( int_c )
write ( * , 100 ) 'int_d', sizeof ( int_d )
write ( * , 110 ) 'aint', aint
write ( * , 110 ) 'bint', bint
write ( * , 110 ) 'cint', cint
write ( * , 110 ) 'dint', dint
write ( * , 110 ) 'selected_int_kind ( INT16 )', selected_int_kind ( INT16 )
100 format ( "Number of bytes in type ", g0, " = ", g0 )
110 format ( "Value of ", g0, " = ", g0 )
end program bytes
这不是错误。标准(Fortran 95 13.14.94、Fortran 2003 13.7.105 和 Fortran 2008 13.7.146)对 selected_int_kind(R)
有这样的说法:
Argument. R shall be an integer scalar.
Result Value. The result has a value equal to the value of the kind type parameter of an integer type that represents all values n in the range −10R < n < 10R, or if no such kind type parameter is available on the processor, the result is −1. If more than one kind type parameter meets the criterion, the value returned is the one with the smallest decimal exponent range, unless there are several such values, in which case the smallest of these kind values is returned.
这意味着,如果 int16
在您的平台上恰好是 2
,则 selected_int_kind(2)
将 return 能够表示范围的最小整数类型 - 100到+100,是一个存储大小为1的单字节,所以int8
的值为returned.
下面一个简单程序的输出应该演示它是如何工作的:
Value of int8 1
Value of int16 2
Value of int32 4
Value of int64 8
Value of selected_int_kind(1) 1
Value of selected_int_kind(2) 1
Value of selected_int_kind(3) 2
Value of selected_int_kind(4) 2
Value of selected_int_kind(5) 4
Value of selected_int_kind(6) 4
Value of selected_int_kind(7) 4
Value of selected_int_kind(8) 4
Value of selected_int_kind(9) 4
Value of selected_int_kind(10) 8
Value of selected_int_kind(11) 8
Value of selected_int_kind(12) 8
Value of selected_int_kind(13) 8
Value of selected_int_kind(14) 8
Value of selected_int_kind(15) 8
Value of selected_int_kind(16) 8
Value of selected_int_kind(17) 8
Value of selected_int_kind(18) 8
Value of selected_int_kind(19) 16
Value of selected_int_kind(20) 16
Value of selected_int_kind(21) 16
Value of selected_int_kind(22) 16
This file was compiled by GCC version 5.2.0 using the options -mtune=generic -march=x86-64 -std=f2008