數值表示法
整數
電腦裡的數值,通常只支援整數和浮點數,目前通常是採用 32 或 64 位元的表示法。
有號整數 (可以表示負數) 通常採用 2 補數表示法,n 位元有號整數的表示範圍是 $-2^{n-1}
$ ~ $(2^{n-1}-1)
$
所以 32 位元有號整數表示範圍為 $-2^{31}
$ ~ $(2^{31}-1)
$ , 64 位元有號整數表示範圍則是 $-2^{63}
$ ~ $(2^{63}-1)
$
浮點數
電腦裡的浮點數同樣採用固定位數的表示法,像是 32 位元的單精度浮點數與 64 位元的雙精度浮點數,都是固定長度的,以下是 IEEE 754 標準 所規定的浮點數的表示規格。
以下是 python 的浮點數規格範圍:
$ python
>>> import sys
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
實數
電腦用浮點數來《近似的表達實數》,但還是會有些微小的誤差,雖然大部分情況下這些誤差不至於造成嚴重問題,但是在《回饋型系統》當中,就會產生像 《蝴蝶效應》 這種《差之毫釐、失之千里》的情況,所以要小心這種誤差的放大效應,特別是經過很多次放大之後的結果。
有理數
所謂的《有理數》 (rational number) 就是可以寫成 p/q 這樣分數的數值,也就是可以表達成 ratio 的 number 。(若採比較口語的譯法,應該是《比例數》)。
雖然浮點數已經可以表示很大範圍的整數,而且非常接近實數,但是浮點數會把 1/3 表示為 0.33333…. 這樣的數值。
>>> 1/3
0.3333333333333333
這種用浮點數代表有理數的方法,對人類而言有時不夠親切與精準,所以 python 用 Fraction 這個物件來表達有理數 (也就是分數)。
>>> from fractions import Fraction
>>> Fraction('3/7')
Fraction(3, 7)
>>> a = Fraction('1/3')
>>> b = Fraction('2/6')
>>> a+b
Fraction(2, 3)
>>> a==b
True
>>> str(a+b)
'2/3'
複數
要用程式實現複數,也只需要用物件方式實作《加減乘除》等運算,就可以完成了,只是其中的《乘除法》算式比較複雜一點,特別是除法最複雜!
加法: $(a + bi) + (c + di) = (a + c) + (b + d)i
$
减法: $(a + bi) - (c + di) = (a - c) + (b - d)i
$
乘法: $(a + bi) (c + di) = ac + bci + adi + bd i^2 = (ac - bd) + (bc + ad)i
$
除法: $\frac{(a + bi)}{(c + di)} = \frac{(a+bi)(c-di)}{(c+di)(c-di)} =\frac{ac+bci-adi-bd i^2}{c^2 -(di)^2}=\frac{(ac+bd)+(bc-ad)i}{c^2+d^2}=\left({ac + bd \over c^2 + d^2}\right) + \left( {bc - ad \over c^2 + d^2} \right)i
$
Python 已經內建了複數型態,以下是複數的基本操作:
>>> a = 1+2j
>>> b = 1-2j
>>> a+b
(2+0j)
>>> a-b
4j
>>> a*b
(5+0j)
>>> a/b
(-0.6+0.8j)
>>> a**2
(-3+4j)
尤拉公式是複數上一個很重要的公式,其中的虛數次方代表旋轉:
$e^{ix}=cos(x) + i sin(x)
$
如果我們用半徑 r 乘上代表單位旋轉的 $e^{ix}=cos(x) + i sin(x)
$ ,也就是採用下列表達式:
$r e^{ix}=r (cos(x) + i sin(x))
$
那麼就可以代表複平面上的任何一個點,其實這就是極座標形式的表示法。
如果我們把 r 寫成 $e^w
$ ,那麼整個算式就可以被《指數化》了,形成下列的複指數形式:
$e^{w+ix}=e^w e^{ix}=r (cos(x) + i sin(x))=a+bi
$
於是當我們對 $a+bi
$ 取《自然對數》 ln 運算時,就會得到
$w+ix = \ln(a+bi)
$
問題是,到底 w,x, 和 a,b 之間該如何轉換呢?
基本上 r 就是半徑,也就是 $r=\sqrt{a^2+b^2}=e^w
$ ,所以 $w = ln(r)=ln(\sqrt{a^2+b^2})=\frac{1}{2} ln(a^2+b^2)
$
而 x 的求法則可直接利用三角函數 $cos(x) = a/r
$ 的關係式,得到:
$x=cos^{-1}(a/r)=cos^{-1}(a/\sqrt{a^2+b^2})
$
於是我們可以得到 w, x 的轉換式如下:
$w={1 \over 2} \ln(a^2+b^2)
$
$x=cos^{-1}(a/\sqrt{a^2+b^2})
$
透過以上的數學, python 已經在 cmath 套件中實作了有關複數的函數,以下是這些函數的範例:
>>> a = 1+2j
>>> import cmath
>>> cmath.exp(a)
(-1.1312043837568135+2.4717266720048188j)
>>> cmath.log(cmath.exp(a))
(1+2j)
>>> cmath.sqrt(a)
(1.272019649514069+0.7861513777574233j)
>>> cmath.polar(a)
(2.23606797749979, 1.1071487177940904)
>>> cmath.phase(a)
1.1071487177940904
>>> cmath.sin(a)
(3.165778513216168+1.9596010414216056j)
>>> cmath.sinh(a)
(-0.4890562590412937+1.4031192506220405j)
小結
現在我們已經認識了 Python 中的《整數、實數、有理數、複數、浮點數》等數值類型的用法。
如果就這樣結束,未免太過可惜,因為這些《數量》所形成的《群體》,是讓我們進入《代數領域》的關鍵。
所以我們將在下一章,探討《代數》這個議題,這可是數學領域中非常重要的一個分支呢?