gfortran Error: Integer too big for its kind at (1)

gfortran Error: Integer too big for its kind at (1)

我想查看 gfortran 的整数类型

所以我写下这行

write(*,"(1X,I20,'correspond to kind  ',I2)"),11111111111,kind(11111111111)

会有编译错误说

precision of type test.f90:67:57: Error: Integer too big for its kind at (1). Th is check can be disabled with the option -fno-range-check

所以我尝试用 -fno-range-check 重新编译。但它给出了结果

-1773790777correspond to kind 4

怎么了?另一方面,intel fortran 没有给出错误和正确答案

可能还有更好的解释,但我是这样理解的。简短的回答是编译器默认为 4 字节整数。

Fortran 是静态类型的,您还没有声明变量类型。编译器被迫使用默认的整数类型,在本例中为 4 个字节。 kind function simply returns the 'kind' of integer used. The compiler is letting you know that you are trying to assign a value too large for a 4 byte integer. When you apply -fno-range-check the compiler ignores this fact and the value overflows, thus the negative value returned. You can specify that the default integer kind be 8 bytes, -fdefault-integer-8. See the gfortran docs

示例 foo.f90:

program foo
    write(*,"(1X,I20,' correspond to kind  ',I2)"),111111111111,kind(111111111111)
    write(*,"(1X,I20,' correspond to kind  ',I2)"),11,kind(11)
end program foo

编译:

$ gfortran -fdefault-integer-8 -o foo.exe foo.f90
$ foo

结果:

111111111111 correspond to kind 8
11 correspond to kind 8

因此您可以看到编译器对您正在测试的实际值无动于衷。

但是,我认为这不是您要尝试做的事情的根源,我认为这是发现特定数值所需的最小整数大小。我不知道有什么方法可以用 Fortran 来做到这一点。请参阅此 here and here 了解您可能能够从 C 移植的解决方案。第二种方法看起来很有希望。在像 Python 这样的动态类型语言中,类型分配是为你处理的。

>>> type(111111111111)
<type 'long'>
>>> type(11111)
<type 'int'>

无论您输入什么值,没有任何种类指定的整数文字始终是默认种类1。因此,甚至询问

也没有多大意义

kind(111111111111)

只要值有效,任何此类文字的种类始终是默认种类。所以和kind(1).

一样

所有整数类型的取值范围都是有限的。您可以使用的最大的

write(*,*) HUGE(1)

在这里,您可以使用您检查的整数类型的任何其他常量或变量来代替 1。大多数情况下,HUGE 的默认值将是 2147483647,对应于 32 位整数。

要使用更大的整数文字常量,请使用更大的 non-default 种类。

使用 Fortran 90 中的方法没关系:

integer, parameter :: lk = selected_int_kind(15)

write(*,*) 11111111111_lk

或来自 Fortran 2008

use iso_fortran_env

integer, parameter :: lk = int64

write(*,*) 11111111111_lk

两者都可以。当然 kind(11111111111_lk) 会 return 的值 lk.


1 这是标准的 Fortran。某些编译器可能会为您将较大的值提升为较大的类型,但仅作为 non-standard 扩展。当转向保持标准行为的编译器时,您可能会感到不愉快。