關於float精度


 

計算機是怎么存小數的?

1000.101 這種二進制小數是「定點數」形式,代表着小數點是定死的,不能移動,如果你移動了它的小數點,這個數就變了, 就不再是它原來的值了。

然而,計算機並不是這樣存儲的小數的,計算機存儲小數的采用的是浮點數,名字里的「浮點」表示小數點是可以浮動的,比如 1000.101 這個二進制數,可以表示成 1.000101 x 2^(-3),類似於數學上的科學記數法。

既然提到了科學計數法,我再幫大家復習一下,比如有個很大的十進制數 1230000,我們可以也可以表示成 1.23 x 10^6,這種方式就稱為科學記數法,該方法在小數點左邊只有一個數字,而且把這種整數部分沒有前導 0 的數字稱為規格化,比如 1.0 x 10^(-9) 是規格化的科學記數法,而 0.1 x 10^(-9) 和 10.0 x 10^(-9) 就不是了。

因此,如果二進制要用到科學記數法,同時要規范化,那么不僅要保證基數為 2,還要保證小數點左側只有 1 位,而且必須為 1,所以通常將 1000.101 這種二進制數,表示成 1.000101 x 2^(-3),其中,最為關鍵的是 000101 和 -3 這兩個東西,它就可以包含了這個二進制小數的所有信息,000101 稱為尾數,即小數點后面的數字,-3 稱為指數,指定了小數點在數據中的位置。

現在絕大多數計算機使用的浮點數,一般采用的是 IEEE 制定的國際標准,這種標准形式如下圖:

Image

這三個重要部分的意義如下:

  • 符號位:表示數字是正數還是負數,為 0 表示正數,為 1 表示負數;

  • 指數位:指定了小數點在數據中的位置,指數可以是負數,也可以是正數,指數位的長度越長則數值的表達范圍就越大;

  • 尾數位:小數點右側的數字,也就是小數部分,比如二進制 1.0011 x 2^(-2),尾數部分就是 0011,而且尾數的長度決定了這個數的精度,因此如果要表示精度更高的小數,則就要提高尾數位的長度;

用 32 位來表示的浮點數,則稱為單精度浮點數,也就是我們編程語言中的 float 變量,而用 64 位來表示的浮點數,稱為雙精度浮點數,也就是 double 變量,它們的結構如下:

Image

 

以上引用部分主要來自參考資料1,該參考資料中還有很多有用的相關知識,可以移步學習。

 float 的尾數部分是 23 位,同時都帶有一個固定隱含位(規定必須為1),故float一共24個二進制有效位。將24個二進制有效位都看作無符號正整數A,則當8 388 608=2^23≤A<10 000 000, A需要7位十進制才可表示,而不確定位最壞的情況下會影響到第7位,所以至少能保證6位有效數字是確定的;當10 000 000≤A≤ 2^24-1=16 777 215時,A需要8位十進制才可表示,而不確定位最壞的情況下會影響到第8位,所以至少能保證7位有效數字是確定的。

 double 的尾數部分是 52 位,同時都帶有一個固定隱含位(規定必須為1),故float一共53個二進制有效位。將53個二進制有效位都看作無符號正整數A,因為某16位數=2^52≤A≤ 2^53-1=某16位數, 故A需要16位十進制才可表示,而不確定位最壞的情況下會影響到第16位,所以至少能保證15位有效數字是確定的。

因此,float最低能保證6個有效位,double最低能保證15個有效位。當然最低能保證,不代表超出的位數就不准確:(1)float中,當10 000 000≤A≤ 2^24-1=16 777 215時,則相應的float最低能保證7個有效位。(2)不確定位不一定確實對末位(尾數區的最右邊一位)產生了不確定性影響;甚至末位更后的位的值也可能是准確的。

 

參考資料:

1. https://blog.csdn.net/flynetcn/article/details/115741534?spm=1001.2014.3001.5506

2. ieee 定義中如何解釋 float 精度為6到7位? - BlueWanderer的回答 - 知乎 https://www.zhihu.com/question/479335091/answer/2065860323


免責聲明!

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



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