Fortran:最大和最小的整数

时间:2012-03-05 15:58:20

标签: fortran fortran95

对我来说,Fortran对我来说是全新的,有人可以帮我解决以下问题吗?我想知道我的电脑上每种类型的所有整数类型数字以及最大和最小值。我的代码如下:

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。

  1. 为什么每种类型的每个最大整数都相同:2147483647?并且是否存在最小整数的内在函数?

  2. 如何在调用子例程rang时保留整数种类号?我认为这是最大整数的关键。

2 个答案:

答案 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"可以实现更多功能。内在函数和其他工具/方法。