CODE {
display: block; /* fixes a strange ie margin bug */
font-family: Courier New;
font-size: 8pt;
overflow:auto;
background: #f0f0f0 url(http://klcintw.images.googlepages.com/Code_BG.gif) lef\
t top repeat-y;
border: 1px solid #ccc;
padding: 10px 10px 10px 21px;
max-height:200px;
line-height: 1.2em;
}
[code]
for i=1 to 10 step 1
for j=1 to 10 step 1
k= i*j
print *, i, j, k
next j
next i
[/code]
2007年1月29日 星期一
前一個程式的計算結果
觀察以下的計算結果,有幾點 值得注意
一 sum > 某一個值得時候,會出現錯誤的 負值答案
二 所需要的計算時間,從 0.0 突然跳到 0.016
可見,比 0.016 小的時間距離,無法被計算出來
三 執行 13.4 億次的加法運算,需要時間約 5.8 秒左右,
從而知道,每秒鐘大概可以執行 兩億個 加法運算,
確實,電腦很快。
[pre]
10 55 0.000000
20 210 0.000000
40 820 0.000000
80 3240 0.000000
160 12880 0.000000
320 51360 0.000000
640 205120 0.000000
1280 819840 0.000000
2560 3278080 0.000000
5120 13109760 0.000000
10240 52433920 0.000000
20480 209725440 0.000000
40960 838881280 0.000000
81920 -939483136 0.000000
163840 536952832 0.000000
327680 -2147319808 0.000000
655360 327680 0.000000
1310720 655360 0.000000
*** 2621440 1310720 0.016000
*** 5242880 2621440 0.031000
*** 10485760 5242880 0.047000
*** 20971520 10485760 0.078000
*** 41943040 20971520 0.172000
*** 83886080 41943040 0.360000
*** 167772160 83886080 0.703000
*** 335544320 167772160 1.375000
*** 671088640 335544320 2.859000
*** 1342177280 671088640 5.828000
Press any key to continue
[/pre]
一 sum > 某一個值得時候,會出現錯誤的 負值答案
二 所需要的計算時間,從 0.0 突然跳到 0.016
可見,比 0.016 小的時間距離,無法被計算出來
三 執行 13.4 億次的加法運算,需要時間約 5.8 秒左右,
從而知道,每秒鐘大概可以執行 兩億個 加法運算,
確實,電腦很快。
[pre]
10 55 0.000000
20 210 0.000000
40 820 0.000000
80 3240 0.000000
160 12880 0.000000
320 51360 0.000000
640 205120 0.000000
1280 819840 0.000000
2560 3278080 0.000000
5120 13109760 0.000000
10240 52433920 0.000000
20480 209725440 0.000000
40960 838881280 0.000000
81920 -939483136 0.000000
163840 536952832 0.000000
327680 -2147319808 0.000000
655360 327680 0.000000
1310720 655360 0.000000
*** 2621440 1310720 0.016000
*** 5242880 2621440 0.031000
*** 10485760 5242880 0.047000
*** 20971520 10485760 0.078000
*** 41943040 20971520 0.172000
*** 83886080 41943040 0.360000
*** 167772160 83886080 0.703000
*** 335544320 167772160 1.375000
*** 671088640 335544320 2.859000
*** 1342177280 671088640 5.828000
Press any key to continue
[/pre]
time1(), time2() 的副程式
這個程式,顯示了 幾點報告
一 從 1 + 2 + ... + 13億
大概花費的時間是 5.8秒
二 時間的計算,有最小的精確度問題,
小於 0.016秒的時間 無法計算
三 整數有其一定的範圍,加法的答案超過 21億
會出現負值
這些問題,將來有需要的時候,會繼續深入研究
[pre]
! file: VF26.F90
! include 'sj-01.inc'
! -----------------------------------------------
subroutine time1(t1)
implicit none
integer t1
! values (5) The hour of the day (range 0 to 23) - local time
! values (6) The minutes of the hour (range 0 to 59) - local time
! values (7) The seconds of the minute (range 0 to 59) - local time
! values (8) The milliseconds of the second (range 0 to 999) - local time
INTEGER DATE_TIME(8)
CHARACTER (LEN= 12) REAL_CLOCK(3)
CALL DATE_AND_TIME(REAL_CLOCK (1), REAL_CLOCK (2), &
REAL_CLOCK (3), DATE_TIME)
! -----------------------------------------------
t1= date_time(5) !hour
t1= t1*60 + date_time(6) !minutes
t1= t1*60 + date_time(7) !seconds
t1= t1*1000 + date_time(8) !milliseconds
end ! of time1()
! -----------------------------------------------
subroutine time2(t1, dt)
integer t1, t2
real dt
call time1(t2)
dt= (t2 - t1)/(1000.0)
! dt must >= 0.0
if (dt < 0.0) then
dt= dt + 1.0*24.0*60.0*60.0
end if
end ! of time2()
! -----------------------------------------------
! begin of main()
implicit none
integer t1, no, sum, i
real dt
no= 10
do while(no > 0)
call time1(t1)
sum= 0
do i=1, no
sum= sum + i
end do
call time2(t1, dt)
if (dt > 0.0) then
write(*, '(1x, A4, 2I12, F10.6)')'*** ', no, sum, dt
else
write(*, '(1x, A4, 2I12, F10.6)')' ', no, sum, dt
end if
no= no*2
end do
end ! of main()
! end of file
[/pre]
一 從 1 + 2 + ... + 13億
大概花費的時間是 5.8秒
二 時間的計算,有最小的精確度問題,
小於 0.016秒的時間 無法計算
三 整數有其一定的範圍,加法的答案超過 21億
會出現負值
這些問題,將來有需要的時候,會繼續深入研究
[pre]
! file: VF26.F90
! include 'sj-01.inc'
! -----------------------------------------------
subroutine time1(t1)
implicit none
integer t1
! values (5) The hour of the day (range 0 to 23) - local time
! values (6) The minutes of the hour (range 0 to 59) - local time
! values (7) The seconds of the minute (range 0 to 59) - local time
! values (8) The milliseconds of the second (range 0 to 999) - local time
INTEGER DATE_TIME(8)
CHARACTER (LEN= 12) REAL_CLOCK(3)
CALL DATE_AND_TIME(REAL_CLOCK (1), REAL_CLOCK (2), &
REAL_CLOCK (3), DATE_TIME)
! -----------------------------------------------
t1= date_time(5) !hour
t1= t1*60 + date_time(6) !minutes
t1= t1*60 + date_time(7) !seconds
t1= t1*1000 + date_time(8) !milliseconds
end ! of time1()
! -----------------------------------------------
subroutine time2(t1, dt)
integer t1, t2
real dt
call time1(t2)
dt= (t2 - t1)/(1000.0)
! dt must >= 0.0
if (dt < 0.0) then
dt= dt + 1.0*24.0*60.0*60.0
end if
end ! of time2()
! -----------------------------------------------
! begin of main()
implicit none
integer t1, no, sum, i
real dt
no= 10
do while(no > 0)
call time1(t1)
sum= 0
do i=1, no
sum= sum + i
end do
call time2(t1, dt)
if (dt > 0.0) then
write(*, '(1x, A4, 2I12, F10.6)')'*** ', no, sum, dt
else
write(*, '(1x, A4, 2I12, F10.6)')' ', no, sum, dt
end if
no= no*2
end do
end ! of main()
! end of file
[/pre]
2007年1月28日 星期日
移出去的副程式,檔案內容不變
目的,是為了讓 主程式 瘦身。
同時,可以將 不同的副程式 歸類,
個別發展,交給不同的人 同時發展,
分工合作。
[pre]
! file: sj-01.inc
subroutine skip1(no)
implicit none
integer no, i
! limits no in 1 .. 20
if ((no >= 1) .AND. (no <= 20)) then
! no is OK!
do i=1, no
print *, ' '
end do
else
! no is invalid
print *, ' '
end if
end ! of sub. skip1()
! -----------------------------------------------
subroutine pause1
implicit none
integer no
print *, 'Input 0 for stop the program, others for continue: '
read(*, '(I2)')no
if (no .EQ. 0) then
stop
end if
end ! of sub. pause1()
! -----------------------------------------------
recursive integer function fs(no)
implicit none
integer no
if (no <= 1) then
fs= 1
return
else
fs= fs(no-1) + fs(no-2)
return
end if
end ! of fs()
! -----------------------------------------------
! end of file
[/pre]
同時,可以將 不同的副程式 歸類,
個別發展,交給不同的人 同時發展,
分工合作。
[pre]
! file: sj-01.inc
subroutine skip1(no)
implicit none
integer no, i
! limits no in 1 .. 20
if ((no >= 1) .AND. (no <= 20)) then
! no is OK!
do i=1, no
print *, ' '
end do
else
! no is invalid
print *, ' '
end if
end ! of sub. skip1()
! -----------------------------------------------
subroutine pause1
implicit none
integer no
print *, 'Input 0 for stop the program, others for continue: '
read(*, '(I2)')no
if (no .EQ. 0) then
stop
end if
end ! of sub. pause1()
! -----------------------------------------------
recursive integer function fs(no)
implicit none
integer no
if (no <= 1) then
fs= 1
return
else
fs= fs(no-1) + fs(no-2)
return
end if
end ! of fs()
! -----------------------------------------------
! end of file
[/pre]
主程式,副程式分離以後的 費氏數列
CODE {
display: block; /* fixes a strange ie margin bug */
font-family: Courier New;
font-size: 8pt;
overflow:auto;
background: #f0f0f0 url(http://klcintw.images.googlepages.com/Code_BG.gif) lef\
t top repeat-y;
border: 1px solid #ccc;
padding: 10px 10px 10px 21px;
max-height:200px;
line-height: 1.2em;
}
請注意 include 這個指令,
三個副程式,已經移到另外的一個檔案,
file: sj-01.inc
如此,我們可以化整為零,各個擊破
[code]
! file: VF26.F90
include 'sj-01.inc'
! -----------------------------------------------
! begin of main()
implicit none
integer no, f1, f2
real r1, r2
integer fs !for function 費氏數列
r2= (1.0 + sqrt(5.0))/2.0
call skip1(3)
print *, 'r2= ', r2
print *, '費氏數列的前後兩項的比值 會趨近於 黃金分割'
! -----------------------------------------------
! 以費氏數列 示範遞迴程式的寫作
call skip1(3)
do no=1, 18, 1
f1= fs(no+1)
f2= fs(no)
r1= float(f1)/float(f2)
print *, 'no= ', no, 'f1= ', f1, ', f2= ', f2, ', r1= ', r1
if ((mod(no, 10)) .EQ. 0) then
call skip1(1)
call pause1
end if
end do
end ! of main()
! -----------------------------------------------
! end of file
[/code]
display: block; /* fixes a strange ie margin bug */
font-family: Courier New;
font-size: 8pt;
overflow:auto;
background: #f0f0f0 url(http://klcintw.images.googlepages.com/Code_BG.gif) lef\
t top repeat-y;
border: 1px solid #ccc;
padding: 10px 10px 10px 21px;
max-height:200px;
line-height: 1.2em;
}
請注意 include 這個指令,
三個副程式,已經移到另外的一個檔案,
file: sj-01.inc
如此,我們可以化整為零,各個擊破
[code]
! file: VF26.F90
include 'sj-01.inc'
! -----------------------------------------------
! begin of main()
implicit none
integer no, f1, f2
real r1, r2
integer fs !for function 費氏數列
r2= (1.0 + sqrt(5.0))/2.0
call skip1(3)
print *, 'r2= ', r2
print *, '費氏數列的前後兩項的比值 會趨近於 黃金分割'
! -----------------------------------------------
! 以費氏數列 示範遞迴程式的寫作
call skip1(3)
do no=1, 18, 1
f1= fs(no+1)
f2= fs(no)
r1= float(f1)/float(f2)
print *, 'no= ', no, 'f1= ', f1, ', f2= ', f2, ', r1= ', r1
if ((mod(no, 10)) .EQ. 0) then
call skip1(1)
call pause1
end if
end do
end ! of main()
! -----------------------------------------------
! end of file
[/code]
加入前面兩個 副程式以後的 費氏數列程式
重複使用的副程式,鞥該能夠獨立在 主程式的外面,
我們 接下來所要討論的主題,
就是 如何解決 這個問題。
[code]
! file: VF26.F90
subroutine skip1(no)
implicit none
integer no, i
! limits no in 1 .. 20
if ((no >= 1) .AND. (no <= 20)) then
! no is OK!
do i=1, no
print *, ' '
end do
else
! no is invalid
print *, ' '
end if
end ! of sub. skip1()
! -----------------------------------------------
subroutine pause1
implicit none
integer no
print *, 'Input 0 for stop the program, others for continue: '
read(*, '(I2)')no
if (no .EQ. 0) then
stop
end if
end ! of sub. pause1()
! -----------------------------------------------
! begin of main()
implicit none
integer no, f1, f2
real r1, r2
integer fs !for function 費氏數列
r2= (1.0 + sqrt(5.0))/2.0
call skip1(3)
print *, 'r2= ', r2
print *, '費氏數列的前後兩項的比值 會趨近於 黃金分割'
! -----------------------------------------------
! 以費氏數列 示範遞迴程式的寫作
call skip1(3)
do no=1, 50, 1
f1= fs(no+1)
f2= fs(no)
r1= float(f1)/float(f2)
print *, 'no= ', no, 'f1= ', f1, ', f2= ', f2, ', r1= ', r1
if ((mod(no, 10)) .EQ. 0) then
call skip1(1)
call pause1
end if
end do
end
! -----------------------------------------------
recursive integer function fs(no)
implicit none
integer no
if (no <= 1) then
fs= 1
return
else
fs= fs(no-1) + fs(no-2)
return
end if
end
! end of file
[/code]
我們 接下來所要討論的主題,
就是 如何解決 這個問題。
[code]
! file: VF26.F90
subroutine skip1(no)
implicit none
integer no, i
! limits no in 1 .. 20
if ((no >= 1) .AND. (no <= 20)) then
! no is OK!
do i=1, no
print *, ' '
end do
else
! no is invalid
print *, ' '
end if
end ! of sub. skip1()
! -----------------------------------------------
subroutine pause1
implicit none
integer no
print *, 'Input 0 for stop the program, others for continue: '
read(*, '(I2)')no
if (no .EQ. 0) then
stop
end if
end ! of sub. pause1()
! -----------------------------------------------
! begin of main()
implicit none
integer no, f1, f2
real r1, r2
integer fs !for function 費氏數列
r2= (1.0 + sqrt(5.0))/2.0
call skip1(3)
print *, 'r2= ', r2
print *, '費氏數列的前後兩項的比值 會趨近於 黃金分割'
! -----------------------------------------------
! 以費氏數列 示範遞迴程式的寫作
call skip1(3)
do no=1, 50, 1
f1= fs(no+1)
f2= fs(no)
r1= float(f1)/float(f2)
print *, 'no= ', no, 'f1= ', f1, ', f2= ', f2, ', r1= ', r1
if ((mod(no, 10)) .EQ. 0) then
call skip1(1)
call pause1
end if
end do
end
! -----------------------------------------------
recursive integer function fs(no)
implicit none
integer no
if (no <= 1) then
fs= 1
return
else
fs= fs(no-1) + fs(no-2)
return
end if
end
! end of file
[/code]
很有用的兩個副程式,skip1(), pause1()
call skip1(3)
跳三行空白
call pause1
暫停 程式的執行,讓你有機會 仔細的觀察
程式的計算結果的輸出,中間值的觀察,
很有用處喔
同時,可以學習 副程式的寫作。
[pre]
! begin of main()
implicit none
integer i
! test skip(), pause
call skip1(3)
do i=1,20,1
call skip1(i)
print *, 'i= ', i, ', i*i= ', i*i, ', sqrt(i)= ', sqrt(float(i))
call pause1
end do
end ! of main()
! -----------------------------------------------
subroutine skip1(no)
implicit none
integer no, i
! limits no in 1 .. 20
if ((no >= 1) .AND. (no <= 20)) then
! no is OK!
do i=1, no
print *, ' '
end do
else
! no is invalid
print *, ' '
end if
end ! of sub. skip1()
! -----------------------------------------------
subroutine pause1
implicit none
integer no
print *, 'Input 0 for stop the program, others for continue: '
read(*, '(I2)')no
if (no .EQ. 0) then
stop
end if
end ! of sub. pause1()
! -----------------------------------------------
[/pre]
跳三行空白
call pause1
暫停 程式的執行,讓你有機會 仔細的觀察
程式的計算結果的輸出,中間值的觀察,
很有用處喔
同時,可以學習 副程式的寫作。
[pre]
! begin of main()
implicit none
integer i
! test skip(), pause
call skip1(3)
do i=1,20,1
call skip1(i)
print *, 'i= ', i, ', i*i= ', i*i, ', sqrt(i)= ', sqrt(float(i))
call pause1
end do
end ! of main()
! -----------------------------------------------
subroutine skip1(no)
implicit none
integer no, i
! limits no in 1 .. 20
if ((no >= 1) .AND. (no <= 20)) then
! no is OK!
do i=1, no
print *, ' '
end do
else
! no is invalid
print *, ' '
end if
end ! of sub. skip1()
! -----------------------------------------------
subroutine pause1
implicit none
integer no
print *, 'Input 0 for stop the program, others for continue: '
read(*, '(I2)')no
if (no .EQ. 0) then
stop
end if
end ! of sub. pause1()
! -----------------------------------------------
[/pre]
訂閱:
文章 (Atom)