計算機組成原理學習15-16 浮點數和定點數

一  定點數

實數怎麼表示,能用二進制表示所有的實數嘛,開始是用BCD編碼來表示

BCD編碼

用 4 個比特來表示 0~9 的整數,那麼 32 個比特就可以表示 8 個這樣的整數。然後我們把最右邊的 2 個 0~9 的整數,當成小數部分;把左邊 6 個 0~9 的整數,當成整數部分。這樣,我們就可以用 32 個比特,來表示從 0 到 999999.99 這樣 1 億個實數了。

BCD編碼缺點

1.此編碼表示的數不夠

          32bit本來可以表示40億個不同的數,但在BCD編碼下,只能表示一億的數

2.這樣的表示方式沒辦法同時表示很大的數和很小的數

 

二 浮點數

用科學計數法表示實數,IEEE的標準有兩種表示浮點數的方式,單精度浮點數float或float32類型的和雙進度浮點數double或double64類型的

浮點數不管是表示還是計算,都是其近似值

單精度類型

單精度的32個比特可以分成三個部分

第一部分是一個符號位,用來表示正數還是負數,用字母s來表示

第二部分是8比特組成的指數位,用e表示,8比特表示的整數空間是0~255,用 1~254 映射到 -126~127 這 254 個有正有負的數上,這裏0和255表示一些特殊的數

第三部分是23比特組成有效位數,用f表示

浮點數的表示如下圖所示:

浮點數中表示特殊值的一些規定

 

以0.5爲例,可以表示成如下形式:

0.5=(−1)0×1.0×2(−1)=0.5

 

三  浮點數的加法和精度損失

兩個浮點數的指數可能是不一樣的,怎麼進行加法了,首先要把指數位調整成一樣,然後計算有效位就好了

例如0.5,表示成浮點數,對應的指數位是 -1,有效位是 00。0.125 表示成浮點數,對應的指數位是 -3,有效位也還是 00。

這兩個數相加時,首先把0.125的指數位-3更改爲-1,對應的有效位 1.00…也要對應右移兩位,因爲 f 前面有一個默認的 1,所以就會變成 0.01,計算兩者相加的有效位1.f,變成了有效位1.01,指數位是-1

從上面可以看出,對於指數較小的數,相加時,有效位需要右移,在右移的過程中,最右側的有效位就被丟棄掉了。這會導致對應的指數位較小的數,在加法發生之前,就丟失精度。兩個相加數的指數位差的越大,位移的位數越大,可能丟失的精度也就越大。

如下程序

 public  static  void main(String[] args){
        float a = 20000000.0f;
        float b = 1.0f;
        float c = a + b;
        System.out.println("c is " + c);
        float d = c - a;
        System.out.println("d is " + d);
    }

結果

c is 2.0E7
d is 0.0

可以看到,精度損失了,下面程序的精度損失更嚴重

 public  static  void main(String[] args){
        float sum = 0.0f;
        for (int i = 0; i < 20000000; i++)
        { float x = 1.0f; sum += x; }
        System.out.println("sum is " + sum);
    }

結果

sum is 1.6777216E7

Kahan Summation 算法

public  static  void main(String[] args){
        float sum = 0.0f;
        float c = 0.0f;
        for (int i = 0; i < 20000000; i++) {
            float x = 1.0f;
            float y = x-c;   //得到進度損失值
            float t =sum+y;
            c=t-sum -y;    //損失值
            sum = t;
        }
        System.out.println("sum is " + sum);
    }

結果

sum is 2.0E7

 

參考資料

https://time.geekbang.org/column/article/97866

https://time.geekbang.org/column/article/98312

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章