如何在Fortran中处理大整数?

弗雷德

我需要生成一些大整数。请参见下面的示例。

Input   Result    
 40 165580141    
 80 37889062373143906    
120 8670007398507948658051921    
160 1983924214061919432247806074196061    
200 453973694165307953197296969697410619233826

这是我的Fortran代码:

program cycle
    use iso_fortran_env
  implicit none
  character(200) :: str
  integer :: n
    integer(kind=int64) :: x1, result, x2, x3

    do n = 40, 500, 40
        x1 = n
        result = 1
        x2 = 0
        x3 = 1
        do 
            if (x1 > 1) then
                x2 = result
                result = result + x3 
                x3 = x2     
                x1 = x1 - 1
            else
                exit
            end if
        end do
        write(str,'(i64)')  result
        print *, n, adjustl(str)
    end do
end program cycle

这是示例输出:

 40 165580141 
 80 37889062373143906 
120 790376311979428689  
160 9217463444206948445 
200 3721511182311577122 

如您所见,它正确地获取了前两个数字,但其余数字超出了64位整数的范围。我看过其他问题(1),但我真的很感兴趣以一种简单的方式,最好是内置在语言本身中。在Ruby和Go中,我没有什么麻烦。我是否忽略了Fortran中明显的内容?我可以在代码中使用更好的选择吗?

罗格维布

没有内置的“大数”支持,但是我们可以首先检查是否有更大的整数类型(如上面的Francescalus所述,以及之前的许多页面(例如,此页面)。)在装有gfortran-6.1的计算机上,编译器似乎支持128位整数类型,因此我最多可以计算n = 160左右的结果。

program cycle
...
integer, parameter :: verylong = selected_int_kind(32)
integer(verylong) :: x1, result, x2, x3

print *, "int32 = ", int32   !! from iso_fortran_env
print *, "int64 = ", int64
print *
print *, "kind..(16) => ", selected_int_kind(16)  !! 8
print *, "kind..(32) => ", selected_int_kind(32)  !! 16
print *, "kind..(40) => ", selected_int_kind(40)  !! -1 (not available)
print *, "kind..(64) => ", selected_int_kind(64)  !! -1 (not available)
print *
print *, "sizeof(x1)       = ", sizeof(x1), "(bytes)"       !! GNU extension
print *, "storage_size(x1) = ", storage_size(x1), "(bits)"  !! F2008
print *, "huge(x1)         = ", huge(x1)                    !! largest integer
...

结果:

 int32 =            4
 int64 =            8

 kind..(16) =>            8
 kind..(32) =>           16
 kind..(40) =>           -1
 kind..(64) =>           -1

 sizeof(x1)       =                    16 (bytes)
 storage_size(x1) =          128 (bits)
 huge(x1)         =  170141183460469231731687303715884105727

 n=          40 res= 165580141
 n=          80 res= 37889062373143906
 n=         120 res= 8670007398507948658051921
 n=         160 res= 1983924214061919432247806074196061
 n=         200 res= 37016692776042937155243383431825151522
 n=         240 res= -159769225356713774587328406036589956191
 ...

虽然没有内置的“ BigInt”类型,但是使用外部库非常简单(例如,从此页面链接的fmlib)。由于各种运算符和分配都过载,因此几乎不需要对代码进行任何修改。

程序:

1)下载文件FMfiles.zip和提取FM.95FMZM90.f95以及FMSAVE.f95

2)制作一个库文件为

gfortran -c -O2 FMSAVE.f95 FMZM90.f95 FM.f95
ar rv fmlib.a FM*.o

3)如下修改您的代码(修改的部分用箭头标记)。

program cycle
    use FMZM           !<----- a module for handling big numbers
    implicit none
    character(200) :: str
    integer :: n
    type(IM) :: x1, result, x2, x3     !<----- IM = BigInt, FM = BigFloat

    do n = 40, 500, 40
        x1 = n
        result = 1
        x2 = 0
        x3 = 1
        do 
            if (x1 > 1) then
                x2 = result
                result = result + x3 
                x3 = x2     
                x1 = x1 - 1
            else
                exit
            end if
        end do
        str = IM_format( 'i200', result )   !<----- convert BigInt to string
        print *, n, trim( adjustl(str) )    !<----- print huge integers
    end do
end program cycle

4)编译(假设“ test.f90”是上面的代码):

gfortran test.f90 fmlib.a
./a.out

5)结果

   n result
  40 165580141
  80 37889062373143906
 120 8670007398507948658051921
 160 1983924214061919432247806074196061
 200 453973694165307953197296969697410619233826
 240 103881042195729914708510518382775401680142036775841
 280 23770696554372451866815101694984845480039225387896643963981
 320 5439356428629292972296177350244602806380313370817060034433662955746
 360 1244666864935793005828156005589143096022236302705537193166716344690085611761
 400 284812298108489611757988937681460995615380088782304890986477195645969271404032323901
 440 65172495098135102433647404982700073500075401759827878315356483347951218369680224170989749666
 480 14913169640232740127827512057302148063648650711209401966150219926546779697987984279570098768737999681

我们可以通过注意resultforn实际上等于fibonacci(n + 1)来验证结果,例如,我们有fibonacci(481) for n = 480

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在python中处理大整数

来自分类Dev

在R中处理大整数

来自分类Dev

在python中处理大整数

来自分类Dev

如何在C ++中处理大于8字节或大于20位的大整数数据

来自分类Dev

如何在python中处理非常大的文件?

来自分类Dev

如何在mysql中设计和处理大表?

来自分类Dev

如何在float中处理非常大的数字

来自分类Dev

如何在C ++中处理最大为2 ^ 9000000的整数

来自分类Dev

javascript如何处理大整数(大于52位)?

来自分类Dev

在算法竞赛中无需BigInteger库即可处理大整数

来自分类Dev

如何在按位运算期间截断大整数以模仿Ruby中的JavaScript?

来自分类Dev

如何在 Pervasive 中自动增加一个大整数

来自分类Dev

如何在Fortran中读取/写入矩阵?

来自分类Dev

如何在Fortran 90中刷新stdout?

来自分类Dev

如何在fortran中读取“ enter”键

来自分类Dev

如何在fortran中添加双标签?

来自分类Dev

如何在Fortran中实施BCD?

来自分类Dev

如何在Fortran 90中刷新stdout?

来自分类Dev

如何在fortran中拆分数组?

来自分类Dev

如何在Laravel App中更好地处理大.scss文件

来自分类Dev

如何在Java中以大十进制反向处理负值?

来自分类Dev

如何在MATLAB中处理“非常大的图像文件”并找出最大的像素

来自分类Dev

如何在文件中读取数字并在Qt中将它们作为整数处理

来自分类Dev

如何在javascript中分割一个大整数

来自分类Dev

在Fortran中捕获整数异常

来自分类Dev

Forth中的大整数?

来自分类Dev

Forth中的大整数?

来自分类Dev

如何在 while 循环中处理整数输入

来自分类Dev

处理中是整数还是整数?