program intkind
implicit none
integer :: n=1
integer :: integer_range =1
do while(integer_range /= -1)
print*, "kind_number ", selected_int_kind(n)
call rang(integer_range)
n = n *2
integer_range = selected_int_kind(n)
end do
contains
subroutine rang(largest)
integer largest
print*, huge(largest)
end subroutine
end
我得到的整数种类数字是:1,2,4,8。
为什么每种类型的每个最大整数都相同:2147483647
?并且是否存在最小整数的内在函数?
如何在调用子例程rang
时保留整数种类号?我认为这是最大整数的关键。
答案 0 :(得分:16)
你的子程序:
subroutine rang(largest)
integer :: largest
print *, huge(largest)
end subroutine
将默认大小的整数作为输入,并输出适合该默认大小整数的最大可能值。它将始终返回巨大的(默认整数),在大多数系统上,它是巨大的(4字节整数)或2147483647. huge
只考虑变量类型;它不会以任何方式解释变量。您可以执行上述尝试的唯一方法是使用参数化派生类型,这些类型足够新,在编译器中对它的支持仍然有点不稳定。
如果你想看看不同的INTINTER的KIND范围,你将不得不使用不同的变量:
program integerkinds
use iso_fortran_env
implicit none
integer :: i
integer(kind=int8) :: i8
integer(kind=int16) :: i16
integer(kind=int32) :: i32
integer(kind=int64) :: i64
integer(kind=selected_int_kind(6)) :: j6
integer(kind=selected_int_kind(15)):: j15
print *,'Default:'
print *, huge(i)
print *,'Int8:'
print *, huge(i8)
print *,'Int16:'
print *, huge(i16)
print *,'Int32:'
print *, huge(i32)
print *,'Int64:'
print *, huge(i64)
print *,''
print *,'Selected Integer Kind 6:'
print *, huge(j6)
print *,'Selected Integer Kind 15:'
print *, huge(j15)
end program integerkinds
跑步给出:
$ ./intkinds
Default:
2147483647
Int8:
127
Int16:
32767
Int32:
2147483647
Int64:
9223372036854775807
Selected Integer Kind 6:
2147483647
Selected Integer Kind 15:
9223372036854775807
答案 1 :(得分:-6)
纯粹作为附录或备用透视图,Fortran变量是根据分配给var的内存字节数定义的。实际上,所有类似的编译器都根据分配的字节来定义变量,否则系统很难在内存中分配/存储,如果没有这样的话,很难执行算术等。
对于一些人来说,像我一样,通过使用稍微更老的符号(而不是"类型的konfusion"更容易看到发生了什么。特别是,很多编译器提供了直接的1:1 Kind和bytes / var之间的对应关系,然后使得最大/最小整数的计算相当简单(某些编译器使用非线性或非直接对应关系)。尽管一定要注意最后的可移植性帮助。例如
Integer(1) :: Int1 ! corresponds to a 1 byte integer
Integer(2) :: Int1 ! corresponds to a 2 byte integer
Integer(4) :: Int1 ! corresponds to a 4 byte integer
Integer(8) :: Int1 ! corresponds to an 8 byte integer
类似的表示法适用于其他Fortran类型(Real,Logical等)。所有var类型都有一个默认的字节数,如果" size"未指定。
特定类型的最大字节数也取决于编译器和系统(例如,所有系统上都没有Integer(16)等)。
一个字节是8位,因此如果从1开始编号,则单个字节应该能够容纳最大值2 ^ 8 = 256,或者当从0开始时,= + 255。
然而,在Fortran中,(几乎所有)数字变量都是"签署"。这意味着在位表示中的某处需要一位来跟踪该数字是+ ve数还是-ve数。所以在这个例子中,最大值是2 ^ 7,因为一位是"丢失/保留"为"签署"信息。因此,有符号的1字节整数可能的值是-127:+128(注意Abs(限制)总和为255,因为" 0"占用一个地方,总共256个&# 34;事情",应该如此)。
类似的规则适用于所有这些变量,只有指数" n",在2 ^ n中,根据字节数而变化。例如,Integer(8)var有8个字节或64位,1位丢失/保留用于符号信息,因此最大可能值为2 ^ 63 = 9223372036854775808(如果从1开始编号)或= 4611686018427387904从0开始。
标准整数数据模型将概括为:
IntNum = s * Sum[ w(k) * 2 ^ (k-1), k=1:(NumBytes*8)-1],
其中s ="签署" (+/- 1),对于第k位值,w(k)为1或0。
不需要在类型声明中使用显式数字或env变量;允许用户定义的编译时常量(即参数)。例如
Integer, Parameter :: DP = Kind(1.0d0) ! a standard Double Precision/8-byte declaration
Integer, Parameter :: I4B = 4 ! NOTICE, here the "Integer" bit has not been explicitly "sized", so defaults to "Integer(4)"
!
Real(DP) :: ADoublePrecReal ! an 8-byte Real (approx 15 decimal places with exp +/- approx 300, see Real data model)
!
Integer(I4B) :: AStandardInt ! a 4-byte integer.
由于Parameter语句可以在另一个可通过Use etc访问的模块中,因此重新编译大型复杂代码以进行" precision"的替代定义是一件简单的事情。期望。例如,如果DP被编辑为Kind(1.0),那么应用声明的所有地方将变为"单精度"实。
Fortran内部函数Huge(),Tiny()等有助于确定给定系统的可能性。
使用Fortran" bit"可以实现更多功能。内在函数和其他工具/方法。