目錄

20200718 想法源起 20200719 我們在做什麼(一) 20200722 我們在做什麼(二) 20200725 竟然成為數學家(一) 20200729 竟然成為數學家(二) 20200801 竟然成為數學家(三) 20200805 不同職級(一) 20200808 不同職級(二) 20200812 趕客系列(一)為什麼讀大學? 20200815 趕客系列(二)不同大學學位跟工作的關係 20200819 趕客系列(三)大學的目的 20200822 趕客系列(四)大學為什麼要有主修 20200826 趕客系列(五)要挑選一個什麼樣的主修 20200829 沒有無緣無故的恨(一) 20200831 科普系列 - 數學與電影動畫製作(一) 20200902 沒有無緣無故的恨(二) 20200905 沒有無緣無故的恨(三) 20200907 科普系列 - 數學與電影動畫製作(二) 20200909 終身職位的評核 20200912 學術界吸引人的地方 20200914 科普系列 - 數學與電影動畫製作 (三) 20200916 學術界辛苦的地方(一) 20200919 學術界辛苦的地方(二) 20200921 科普系列 - 數學與電影動畫製作 (四) 20200923 大學的讀書成績有多重要 20200926 本科生研究機會 20200928 科普系列 - 數學與圖像修復(一) 20200930 用創新的方法去教育科學 20201003 參加研討會的重要 20201005 科普系列 - 數學與圖像修復(二) 20201007 教授與教學 20201010 研究是什麼(一) 20201012 科普系列 - 數學與圖像修復(三) 20201014 研究是什麼(二) 20201017 研究是什麼(三) 20201019 科普系列 - 數學與圖像修復(四) 20201021 如何閱讀研究論文 20201024 研究生應該修什麼課 20201026 科普系列 - 數學與圖像修復(五) 20201029 本科生的多主修多副修 20201102 科普系列 - 數學與數獨(一) 20201105 幾位教授(一) 20201109 科普系列 - 數學與數獨(二) 20201112 幾位教授(二) 20201116 科普系列 - 數學與數獨(三) 20201119 幾位教授(三) 20

計算數學入門系列 - 數值表示方式(二)



通常我們介紹這些實數的標示方式,開始時都會用single precision 作為切入,如果同學有用C/C++, 在設定variable 的時候就會用到float 這一個class ,如果還有人在寫FORTRAN,用的就是real 這一個class。Single precision 只會用4 bytes (32 bits,意思就是說會用32個0或者1) 去代表一個實數。 表示的方式,會是 \( (-1)^s 2^{e-127} 1.f\)。s代表Sign,是32 bits 裏面的第一個bit,用來代表這個數字是正數還是負數,0 代表正數,1代表負數。 然後的1 byte = 8 bits 是e (代表exponent),會先化為一個整數, 再減去127。 剩餘的23 bits,叫作mantissa,每一個bit 的數值會用二進制小數點的數位值慢慢遞減。 例如,這23bits 裏面的第一個bit, 數位值就是½,第二bit 的數位值就是¼,如此類推。

如果e=0,無論s 或者f 是什麼,數值所代表的都是實數0.0。而如果\(e=11111111_{(2)}=255_{(10)}\),情況就有點不同。如果f=0,數值所代表的就是正無限大或是 負無限大 (根據s 是等於0還是等於1)。而如果f 是其他東西,就是同學最不知所措的NaN (Not A Number)。 通常這些情況,就很可能是同學在編寫程式時有Bug。中間一定有一些在編程時的問題。

舉個例子,\( 1.0 = (-1)^0 2^{127-127} 1.0\) 在single precision 裏面的表示方式是,
\[0 01111111 000000000000000000000000000。\]
那麼,最接近0的正實數是那一個數字呢? 由於e不可以是0,我們要找的這個數字 的數值表示方式是 \( (-1)^0 2^{1-127} 1.0 = 2-126_{(10)}\),大約等於\(1.2\times10^{-38}\)。另外一個有趣的問題,是問,最接近1 而又比1大的實數是那一個數目字。 這個數字的數值表示方式是
\[0 01111111 000000000000000000000000001。\]
把它換回十進制,我們得到 \( (1+2^{-23})_{(10)}\) 。 因為這一個數值\(2^{-23}\) 非常重要,我們給了他一個名字叫做machine epsilon,用 \(\epsilon\) 來表示。


從這些例子裏面,我們可以看到兩個很特別的地方。第一個,是我們沒有辦法把數線 上面所有的數目字在電腦裏面表示出來。如果我們用的是single precision,可以想像我們是沒有辦法表示\(10^{-38}\) 這個數目字。當然,大部份情況我們都不需要用到這麼小的一個數字。如果真的有需要,我們可以用double precision 代替single precision。這個表示方式,就不只用4 bytes,而是用到8 bytes。有興趣的同學,可以嘗試在MATLAB 或者Octave 裏面輸入

>> eps
ans =
     2.220446049250313e-16

去找出machine epsilon。就會見到在這兩個軟件裏面的變數就是用了double precision 去表達。其他關於這個表示方式就不在這裏多討論了。 可是由於我們只會使用有限的資源,可以想像能夠表達出來的數字也只有有限的那麼多個。舉個例來說, \(\sqrt2\) 就不可能用上面的方式寫出來。有同學可能會得到這個觀察結果,「哦,根據定義,我們可以表達的當然只可能是有理數 (Rational Number)。這個是無理數 (Irrational Number) ,所以就沒有關係了。」 對,不單如此,因為有理數還是有無限多,可以想像有很多無理數我們還是沒有辦法表示出來。三分之一就是其中一個例子。 

留言