深入淺出計算機組成原理學習筆記:第十六講


你是不是感到很疑惑,浮點數的近似值究竟是怎么算出來的?浮點數的加法計算又是怎么回事兒?在實踐應用中,我們怎么才用好浮點數呢?這一節,我們就一起來看這幾個問題

一、浮點數的二進制轉換

1、十進制浮點數9.1

2、小數的二進制表示是怎么回事

 

3、浮點數其實是用二進制的科學計數法來表示的

 

4、為什么0.3+0.6=0.899999?

二、浮點數的加法和精度

1、浮點數的加法原理

2、比如0.5,表示成浮點數

 

實現這樣一個加法,也只需要位移。和整數加法類似的半加器和全加器的方法就能夠實現,在電路層面,也並沒有引入太多新的復雜性。

3、這個加法計算的浮點數的結果是不是正確

1、先對齊

2、在加法發生之前,就丟失精度

3、32位浮點數的加法

你可以試一下,我下面用一個簡單的Java程序,讓一個值為2000萬的32位浮點數和1相加,你會發現,+1這個過程因為精度損失,被“完全拋棄”了。

public class FloatPrecision {
  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

三、Kahan Summation算法

那么,我們有沒有什么辦法來解決這個精度丟失問題呢?雖然我們在計算浮點數的時候,常常可以容忍一定的精度損失,但是像上面那樣,
如果我們連續加2000萬個1,2000萬的數值都會被精度損失丟掉了,就會影響我們的計算結果。

在機器學習中的應用

我們可以做一個簡單的實驗,用一個循環相加2000萬個1.0f,最終的結果會是1600萬左右,而不是2000萬。這是因為,

加到1600萬之后的加法因為精度丟失都沒有了。這個代碼比起上面的使用2000萬來加1.0更具有現實意義。

public class FloatPrecision {
  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的算法來解決這個問題。

算法的對應代碼我也放在文稿中了。從中你可以看到,同樣是2000萬個1.0f相加,用這種算法我們得到了准確的2000萬的結果

public class KahanSummation {
  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 1.6777216E7

其實這個算法的原理其實並不復雜,就是在每次的計算過程中,都用一次減法,把當前加法計算中損失的精度記錄下來,然后在后面的循環中,把這個精度損失放在要加的小數上,再做一次運算。

如果你對這個背后的數學原理特別感興趣,可以去看一看Wikipedia鏈接里面對應的數學證明,也可以生成一些數據試一試這個算法。這個方法在實際的數值計算中也是常用的,也是大量數據累加

中,解決浮點數精度帶來的“大數吃小數”問題的必備方案

四、總結延伸

1、浮點數的缺點

 

2、浮點數不適合的場景

3、浮點的應用場景


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM