real x
x 的 default 是 4-bytes
等於 32個 bits
= 1 + 8 + 23
其中的 23個 bits 就是拿來當作 精確度使用
2^23 等於 8,388,608
電腦把 一個浮點數 拆開,變成三個部份
1- bits 所代表的是 浮點數的 正,或是負
8- bits 所代表的是 次方
接著,把 0.0 到 1.0 , 切成 8,388,608 這麼多等分,
1.0/8,388,608 得到的,就是 精確度,就是 有效位數
答案是 1.1921 X (10^ -7)
所以,有效位數是 6 到 7位
如何使用一個 fortran 程式去證明,
下回分解。
dx= 0.2116555
dx= 0.1058277
dx= 5.2913874E-02
dx= 2.6456937E-02
dx= 1.3228469E-02
dx= 6.6142343E-03
dx= 3.3071171E-03
dx= 1.6535586E-03
dx= 8.2677929E-04
dx= 4.1338964E-04
dx= 2.0669482E-04
dx= 1.0334741E-04
dx= 5.1673705E-05
dx= 2.5836853E-05
dx= 1.2918426E-05
dx= 6.4592132E-06
dx= 3.2296066E-06
dx= 1.6148033E-06
dx= 8.0740165E-07
dx= 4.0370082E-07
dx= 2.0185041E-07
dx= 1.0092521E-07
exit the loop, and ...
x1, x2, dx= 2.718282 2.718282 1.0092521E-07
Fortran Pause - Enter command<CR> or <CR> to continue.
以上的結果顯示,有效位數是 6 ... 7 位
!dec$end if
! -----------------------------------------------
implicit none
real x1, x2, dx
! 一開始,有兩條繩子,其長度分別是 x1, x2
x1= 4.0*atan(1.0)
x2= exp(1.0)
! 這兩條繩子的長度的差是 dx
dx= x1 - x2
print *, 'x1, x2, dx= ', x1, x2, dx
pause
! -------------------------------------------
do while (x1 > x2)
dx= dx/2.0 ! 每次的 loop, 都把誤差減半
x1= x2 + dx
print *, 'dx= ', dx
end do
! x1 <= x2
! 以上的 loop, 在數學上,dx 永遠會大於 0, 所以
! x1 會永遠大於 x2,
! 但是,竟然會發生 (x1 <= x2)
! 這是因為,電腦的有效位數是有限的 的關係
print *, ' '
print *, 'exit the loop, and ...'
print *, 'x1, x2, dx= ', x1, x2, dx
pause
end
x1, x2, dx= 3.14159265358979 2.71828182845905
0.423310825130748
Fortran Pause - Enter command<CR> or <CR> to continue.
dx= 0.211655412565374
dx= 0.105827706282687
dx= 5.291385314134350E-002
dx= 2.645692657067175E-002
dx= 1.322846328533588E-002
dx= 6.614231642667938E-003
dx= 3.307115821333969E-003
dx= 1.653557910666984E-003
dx= 8.267789553334922E-004
dx= 4.133894776667461E-004
dx= 2.066947388333731E-004
dx= 1.033473694166865E-004
dx= 5.167368470834326E-005
dx= 2.583684235417163E-005
dx= 1.291842117708582E-005
dx= 6.459210588542908E-006
dx= 3.229605294271454E-006
dx= 1.614802647135727E-006
dx= 8.074013235678635E-007
dx= 4.037006617839318E-007
dx= 2.018503308919659E-007
dx= 1.009251654459829E-007
dx= 5.046258272299147E-008
dx= 2.523129136149573E-008
dx= 1.261564568074787E-008
dx= 6.307822840373934E-009
dx= 3.153911420186967E-009
dx= 1.576955710093483E-009
dx= 7.884778550467417E-010
dx= 3.942389275233709E-010
dx= 1.971194637616854E-010
dx= 9.855973188084271E-011
dx= 4.927986594042136E-011
dx= 2.463993297021068E-011
dx= 1.231996648510534E-011
dx= 6.159983242552670E-012
dx= 3.079991621276335E-012
dx= 1.539995810638167E-012
dx= 7.699979053190837E-013
dx= 3.849989526595419E-013
dx= 1.924994763297709E-013
dx= 9.624973816488546E-014
dx= 4.812486908244273E-014
dx= 2.406243454122137E-014
dx= 1.203121727061068E-014
dx= 6.015608635305341E-015
dx= 3.007804317652671E-015
dx= 1.503902158826335E-015
dx= 7.519510794131677E-016
dx= 3.759755397065838E-016
dx= 1.879877698532919E-016
exit the loop, and ...
x1, x2, dx= 2.71828182845905 2.71828182845905
1.879877698532919E-016
Fortran Pause - Enter command<CR> or <CR> to continue.
以上的結果顯示,有效位數是 15 ... 16 位
!dec$end if
! -----------------------------------------------
implicit none
real*8 x1, x2, dx
! 一開始,有兩條繩子,其長度分別是 x1, x2
! 當你採用double precession 的函數 Datan(), Dexp()
! 的時候,你的參數input, 要改成 1.0D0 的 double 規格
x1= 4.0*Datan(1.0D0)
x2= Dexp(1.0D0)