【问题标题】:Fortran: handling integer values of size: ~700000000000Fortran:处理大小的整数值:~700000000000
【发布时间】:2011-01-24 07:50:22
【问题描述】:

目前我正在复习我的 Fortran95 知识(不要问为什么)...

我遇到了一个问题。如何处理大整数,例如。大小:~700000000000

INTEGER(KIND=3) 无法保存此数字。 如果有人感兴趣,我可以使用的编译器是 Silverfrost FTN95。

我正在使用整数来遍历更大的数据集。

你有什么建议吗?

【问题讨论】:

  • 如果有人可能会问,你需要这样的范围吗?

标签: integer fortran numbers long-integer


【解决方案1】:

标准解决方案(从 Fortran 95 开始,所以我假设您的编译器支持它)是使用 SELECTED_INT_KIND 内在函数来探测有效的整数类型(其值取决于编译器)和 HUGE 内在函数。

  • SELECTED_INT_KIND (R) 返回整数类型的 kind 类型参数,它表示所有整数值 n,其中 -10^R
  • HUGE (K) 返回 K 类整数类型中可表示的最大数。

例如,在我的带有 x86_64 处理器(gfortran 编译器,64 位模式)的 Mac 上,以下程序:

  print *, selected_int_kind(1)
  print *, selected_int_kind(4)
  print *, selected_int_kind(8)
  print *, selected_int_kind(16)
  print *, selected_int_kind(32)
  print *, selected_int_kind(64)
  print *, huge(0_1)
  print *, huge(0_2)
  print *, huge(0_4)
  print *, huge(0_8)
  print *, huge(0_16)
  end

输出:

           1
           2
           4
           8
          16
          -1
  127
  32767
  2147483647
  9223372036854775807
 170141183460469231731687303715884105727

这告诉我我会为你的工作使用integer(kind=8)

【讨论】:

  • 种类号码不可携带。特别是考虑到 OP 使用 kind=3 和 Silverfrost Fortran,那么 kind=8 不是一件好事。 Silverfrost Fortran 中没有种类 8。至少在正常情况下不会。如其他答案所示,可以直接在命名常量中使用selected_int_kind (12)
【解决方案2】:

声明一个至少有 12 个十进制数字的整数“索引”的可移植性是:

integer, parameter :: MyLongIntType = selected_int_kind (12)
integer (kind=MyLongIntType) :: index

"kind=" 可以省略。

使用 3 等特定值是完全不可移植的,不推荐使用。一些编译器连续使用类型编号,其他编译器使用字节数。 “selected_int_kind”将返回编译器可用的最小整数种类的种类号,它可以表示请求的位数。如果不存在该类型,则返回-1,使用 kind 值声明整数时值会失败。

gfortran 和 ifort 都返回一个类型,用于输入到 selected_int_kind 最多 18 位的十进制数字。大值(例如 18)通常会选择一个最大正值为 9223372036854775807 的 8 字节整数。它有 19 位数字,但如果编译器支持这种类型但不支持更长的类型,selected_int_kind (19) 将是 -1,因为不是所有的 19 位整数都是可表示的。

【讨论】:

    【解决方案3】:

    有许多可用于 Fortran 的免费 arbitrary-precision 库可以解决这个问题。 FMLIB 是其中之一。还有五六个替代方案是linked from this page

    【讨论】:

      【解决方案4】:

      如果您将它用作循环控制变量,但不直接使用整数(我想您不能这样做,因为您不能声明一个大于可表示的最大索引的数组,对吧?) ,那么我想要做的就是将那只小狗除以 100000 之类的东西,然后将它的循环嵌套在另一个循环中,该循环重复了很多次。

      【讨论】:

      • 不幸的是我..问题实际上是找到一个巨大数字的最大素数的问题..最初的想法是纯粹的蛮力,如果我找到了一个聪明的解决方案。当前的想法是,以下但由于明显的原因实际上不可能: INTEGER :: I=0,J=0,STATE=0,LARGE_DIV=0 long MAX=7100000000000 DO I=2,MAX STATE=0 DO J=2,I IF (MOD(I,J)==0) STATE=STATE+1 IF (STATE>=2) EXIT END DO IF (STATE >=2) CYCLE IF (MOD(MAX,I)== 0) LARGE_DIV=I END DO WRITE(,)LARGE_DIV
      • 这听起来像是 bignum 图书馆的工作。 Fortran 肯定有一个...
      【解决方案5】:

      你试过 INTEGER(KIND=4) 吗?

      【讨论】:

      • 是的..据我所知,允许的最高修改是 kind=3.. 编译器错误将是:C:\FTN_Projects\xxxxxx.F95(3):错误 217 - INTEGER( KIND=3) 常量超出范围 (kind=3) 由编译器设置,提供的参数是 kind=4
      【解决方案6】:

      我们对此的回答是将值放入双精度变量中并对其执行 DINT 以消除任何小数部分。 结果是放置在双精度变量中的整数。 函数 DINT 并不总是可用于所有 FORTRAN。该函数是一个双精度整数函数,这将允许非常大的整数(最多 17 位)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-25
        • 2017-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-02
        • 1970-01-01
        相关资源
        最近更新 更多