gpt4 book ai didi

fortran - 如何在 Fortran 中计算大整数?

转载 作者:行者123 更新时间:2023-12-01 19:29:28 28 4
gpt4 key购买 nike

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

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 以及许多之前的页面所提到的(例如 this page )。在我的计算机上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 链接的 this page )。由于各种运算符和赋值都被重载,因此几乎不需要对代码进行任何修改。

程序:

1) 下载文件FMfiles.zip并提取 FM.95FMZM90.f95FMSAVE.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

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

关于fortran - 如何在 Fortran 中计算大整数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38801846/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com