二進位小數表示法

冪次方

冪次方是一個神奇的東西,  比如 42 = 4*4, 53=5*5*5

數學上, 乘法總是比加法複雜, 如果有個方法可以把乘法變成加法來運算的話, 這天下就美滿了. 幸運的是, 還真的有這種方法.  比如 1024*512, 這個要動動筆吧
1024*512 = 210*29 = 219
如何呢, 上面的指數, 直接變成相加的即可

即然有 53, 52, 51, 那 50呢, 答案是 1.
那是否有5-1呢!! 有的, 答案是 1/5, 5-2就是 1/25

小數

二進位的小數和十進位的小數在觀念上完全一樣, 必須有一個小數點, 小數點的左邊是整數, 小數點的右邊是小數, 每一位數有它的權重, 例如下圖:

number

在電腦裡表達小數的方式有兩種, 一種是定點表示法, 一種是浮點表示法

定點小數表示法(fixed point)

在電腦裡資料以位元來存放, 而小數點並不需要真的存放在位元內, 我們只要知道哪兩個位元之間是小數點就好了

使用定點表示法來表達小數時會將小數點都固定在一個地方, 而不會變來變去, 這也是為什麼要叫做定點小數的原因

定點小數表示法裡加減法就是二進位的標準加減法, 而乘法必須要把小數點移回來

高階程式語言內一般都不用定點小數表示法, 因為定點小數表示法所能表示數字的範圍非常有限, 例如上面雙位元組小數點置於第 8 位和第 9 位元之間時, 只能表示 0 到 255 之間每隔 1/256 的那些數字而已. 這樣子範圍的數字在自然界中應用的機會較小, 那為什麼要用這種方式表示小數呢?? 簡單地說就是運算速度較快, 定點小數的運算就是標準二進位的運算, 因此很簡單, 硬體製作起來也很便宜

十進位的小數使用二進位定點表示法時, 可能會有誤差, 比如十進位的 0.1 使用二進位表示時是 0.000110011001100110011… 的一個循環小數, 以上圖的表示法來說小數以下只能表示八位數, 也就是 0.00011001, 這個數字和原來希望表示的數字會有一點點的誤差, 讓我們把這個數字換回十進位來看看, 也就是 1/256 + 1/32 + 1/16 = 25/256 = 0.09765625, 只能很接近 0.1. 誤差一定小於 1/256,  而且有一個特性就是實際表達出來的數字的絕對值永遠小於或是等於原來要表達的數字的絕對值

浮點小數表示法

二進位的浮點小數表示法 (或是浮點數, floating point number) 和我們十進位中常用的科學記號表示法類似. 十進位中我們用10的冪次 (power) 及 0 至 1 之間的小數來表示一個任意的實數, 如 12345.6789 可以寫成 0.123456789 * 105

在二進位中我們一樣可以將一個二進位數字 1101110.11011 表示為 0.110111011011 * 27, 這樣的表示法和定點表示法有什麼不同嗎? 這兩個數值的大小當然是完全一樣, 但定點小數表示法中我們看到它的缺點是絕對值太大的數字會被截斷(溢位overflow), 位數不夠多無法表達大於範圍的數字, 絕對值太小的數 (0.000000001) 也會被截斷 (無條件捨去法truncation) 只能表達近似的值

想一下底下二個問題

1. 對於一個很大的數字 (123456789012) 定點表示法保証小數點以後一定有固定的幾個位數來表示 (例如00000011), 可是這樣子的精確度對於大部份的應用來說是沒什麼意義. 試想太陽到地球的距離多一公里少一公里真的有關係嗎? 光速每秒鐘快一公尺又何妨?

2. 對於一個很小的數字 (例如0000000012) 來說定點表示法可能因為小數點後沒有足夠的位數來記錄而將其省略. 上面這個數字就變成 0 了. 如果水中含有 0.0000000012 莫耳的氰化鈉, 這是會喝死人的. 但因為小數點後位數不足而把它當為 0, 這下又喝不死人了.

此時浮點數表示法就有其功用了. 以第一例中一個很大的數字而言, 浮點數由最重要的位數開始只保留一定的位數, 例如 123456789012.00000011 可用 0.1234567890 * 1012 來表示就夠了, 這個表達方法所記錄的數字和實際的數字會有誤差, 但是百分比誤差不大. 以第二例而言, 0.0000000012 可用 0.12 * 10-8 來表示, 不需浪費許多位元記錄 “0”, 只需記 12 以及 -8 即可精確地表達這個很小的數字

32位元二進位浮點表示法(float), 以1個位元記錄正負號, 7個位元記錄 2 的冪次, 24 個位元記錄小數, 共 32 位元, 如下圖所示

number2

若有一個以此種表示方法的二進位數值:

0 0001110 110000000000000000000000

代表十進位的 0.75 * 214

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *