- UID
- 2393
- 性别
- 男

超凡脱俗
- 积分
- 796
F 币- 474 元
- 最后登录
- 2023-8-6
贡献- 237 点
- 注册时间
- 2017-2-16
权杖- 11 枚
惯用编译器:GFortran / G77 for Linux

专家
超凡脱俗
F 币- 474 元
贡献- 237 点
|
本帖最后由 Jackdaw 于 2018-2-5 09:05 编辑
丁酉年癸丑月丙寅日,遇群友讨论大数阶乘,遂编制代码实现之,与朋友们分享(我不会说我是为了装X的 )。
此文分三部分内容,源码+Makefile+测试结果
测试电脑:Ubuntu 16.04.3 LTS 64-bit CPU: i5-4210M@2.6GHz
源码:
[Fortran] 纯文本查看 复制代码 004 | integer , parameter :: id = 4 |
005 | integer ( id ) :: num_zeros |
006 | integer ( id ) , allocatable :: fact ( : ) |
007 | integer ( id ) :: n = 12000 |
008 | integer ( id ) , parameter :: n_digit = 5 |
009 | integer ( id ) , parameter :: critical = 10 * * n_digit |
026 | subroutine finalize ( ) |
029 | end subroutine finalize |
031 | integer ( id ) function digit ( a ) |
033 | integer ( id ) , value :: a |
035 | do while ( a .ne. 0 ) |
041 | subroutine carry_forward ( ) |
046 | if ( fact ( j ) .ne. 0 ) exit |
050 | if ( fact ( i ) .ge. critical ) then |
051 | tmp = mod ( fact ( i ) , critical ) |
052 | fact ( i +1 ) = fact ( i +1 ) + fact ( i ) / critical |
054 | if ( i .eq. up ) up = up +1 |
057 | end subroutine carry_forward |
059 | subroutine carry_back ( ) |
063 | if ( fact ( i ) .ne. 0 ) exit |
065 | num_zeros = num_zeros + ( i - 1 ) * n_digit |
066 | fact ( 1 : up - i +1 ) = fact ( i : up ) |
069 | end subroutine carry_back |
075 | write ( * , "(i5.5)" , advance = "no" ) fact ( i ) |
076 | if ( mod ( up - i +1 , 35 ) .eq. 0 ) write ( * , * ) |
078 | write ( * , "(a,g0)" ) " E+" , num_zeros |
079 | end subroutine display |
082 | subroutine factorial ( num ) |
084 | integer ( id ) , intent ( in ) , value :: num |
085 | integer ( id ) :: i , j , k , npos |
086 | integer ( id ) , allocatable :: mod_i ( : ) |
087 | integer ( id ) , allocatable :: tmp_fact ( : ) |
091 | if ( .not. allocated ( tmp_fact ) ) allocate ( tmp_fact ( n ) ) |
095 | if ( .not. allocated ( mod_i ) ) allocate ( mod_i ( npos ) ) |
098 | mod_i ( j ) = mod ( tmp , critical ) |
101 | if ( npos .ge. critical ) then |
104 | if ( mod_i ( j ) .eq. 0 ) cycle |
106 | forall ( k = 1 : up ) tmp_fact ( k + j -1 ) = tmp_fact ( k + j -1 ) + fact ( k ) * mod_i ( j ) |
108 | if ( tmp_fact ( k ) .ge. critical ) then |
109 | tmp = mod ( tmp_fact ( k ) , critical ) |
110 | tmp_fact ( k +1 ) = tmp_fact ( k +1 ) + tmp_fact ( k ) / critical |
119 | forall ( k = 1 : up ) fact ( k ) = fact ( k ) * i |
123 | if ( npos .ne. digit ( i +1 ) ) deallocate ( mod_i ) |
130 | if ( allocated ( tmp_fact ) ) deallocate ( tmp_fact ) |
131 | end subroutine factorial |
132 | end module factorial_mod |
140 | write ( * , * ) "Please input a positive integer number(not greater than 13500):" |
142 | call system_clock ( t ( 1 ) , t ( 3 ) ) |
144 | call system_clock ( t ( 2 ) , t ( 3 ) ) |
145 | write ( * , "(a,f7.3,a)" ) " Time :" , ( t ( 2 ) - t ( 1 ) ) * 1.0 / t ( 3 ) , " s" |
Makefile:
[Bash shell] 纯文本查看 复制代码 08 | $(FC) $(FF) $(SC) -o $(XX) |
11 | rm -rf *.mod *.txt $(XX) |
测试结果:
分别为10、 100、 300、 1000的阶乘
10000的阶乘(0.224秒)
ps:屏幕太小放不下了
|
|