準確詳解:C/C++ float、double資料型別的表示範圍及精度
今天覆習C++遇到了float、double資料型別的表示範圍及精度問題,花費了一些時間重新梳理了一遍,鑑於網上很多文章寫的並不清晰,並且有不少疏漏錯誤之處,特結合個人理解仔細整理如下。
要弄清楚這個問題,首先要搞清楚浮點數在記憶體中的儲存方式。浮點數,區別於定點數,指的是小數點位不確定的的資料型別,其原理是將一個浮點數a用兩個數m(尾數)和e(指數)來表示:a = m × b^e。其中的b為選取的基數。科學計數法就是一種特殊形式的浮點數。
在計算機二進位制表示中,浮點數採用2作為基數,規定尾數的範圍為1.0~2.0之間。
以float型別為例,根據最廣泛採用的IEEE754標準規定,float資料型別長度為32位,其中最高位為符號位,中間8位為指數位,最後23位作為尾數位。
最高位符號位通過0/1來區分正負,0正1負;指數位則規定採用移碼的形式儲存,這樣可以保證指數部分為無符號數,方便比較大小。移碼錶示法是在數X上增加一個偏移量來定義的,如果機器字長為n,規定偏移量為2^(n-1),對於8位補碼-128~127,可得到對應的階碼錶示為0~255,其中全0和全1分別用來表示0和無窮大,故規定1~254用來表示規範數字,即對應指數範圍從-126到127;尾數部分統一規定為1.0-2.0之間,最高位必然為1,故可以省略,所以尾數部分從小數點後算起,最小可以取到1,最大則取到二進位制1.1...1(小數點後23位),即取到2-2^-23,可近似約等於2。故得到float絕對值的最大值取到2^127*(2-2^-23)約等於2^128=3.4E+38。加上符號之後可得float表示範圍為(-3.4E+38)~(3.4E+38)。當然實際是取不到的,開區間。絕對值最小則可以取到2^-127*1,即為1.175E-38。
接下來解釋精度。由於尾數部分位數是固定的小數點後23位,23位所能表示的最大數是2^23−1=8388607,所以十進位制的尾數部分最大數值是8388607,也就是說尾數數值超過這個值之後,float將無法精確表示,所以float最多能表示小於8388607的小數點後7位,但絕對能保證的為6位,也即float的十進位制的精度為為6~7位。
double資料型別的推算過程和上述同理,唯一的區別在於尾數由23位擴充套件到52位,階碼由8位增加到了11位,計算方法不變。所以double的階碼(移碼錶示)為1~2046,偏移量為1023,故指數範圍為-1022~1023,得表示範圍為(2^1023*2)~(-2^1023*2)即為-1.7E+308~1.7E+308,絕對值最小可以取到2^-1022,精度則為2^52-1=4503599627370495,為16位。所以精度最高位16位,一定可以保證15位。
相關文章
- float double 型別資料極值表示型別
- c++ 基本資料型別(int、float、double、long、long long)最大值,最小是表示方法C++資料型別
- int/double資料範圍
- C C++變數型別大小和範圍C++變數型別
- 資料型別範圍資料型別
- java double、float型別的比較Java型別
- Java面試官:兄弟,你確定double精度比float低嗎?Java面試
- C++引用型別詳解C++型別
- C++之string型別詳解C++型別
- C++資料型別C++資料型別
- c語言中%f輸出double型和float型值C語言
- C++ 使用者輸入與資料型別詳解:建立基本計算器及變數型別C++資料型別變數
- Java個人學習筆記-資料型別及取值範圍Java筆記資料型別
- 【C++】資料型別-列舉型C++資料型別
- C++ 表示式中的型別轉換C++型別
- 微控制器中的資料型別佔用空間及取值範圍資料型別
- C++檢視資料型別C++資料型別
- PHP 對 float 型別使用 JSON_encode () 精度缺失PHP型別JSON
- [JAVA] Java 變數、表示式和資料型別詳解Java變數資料型別
- C#資料型別及其轉換詳解C#資料型別
- PHP基礎-資料型別-floatPHP資料型別
- Double型別數值相加導致精度缺失問題型別
- c++ 16進位制資料轉doubleC++
- C語言 int,float,double整型和浮點型資料在相互運算時bug原因C語言
- C++ 數學函式、標頭檔案及布林型別詳解C++函式型別
- float和double有什麼區別?
- Java深海拾遺系列(5)--- 精度計算中的BigDecimal,double和floatJavaDecimal
- XML Schema 字串資料型別及約束詳解XML字串資料型別
- decimal,float和double的區別是什麼?Decimal
- 詳解MySQL資料型別MySql資料型別
- MySQL 資料型別詳解MySQL 資料型別
- JavaScript——資料型別詳解JavaScript資料型別
- Java:利用BigDecimal類巧妙處理Double型別精度丟失JavaDecimal型別
- ETL過程中資料精度不準確問題
- C++的資料型別總結,不能錯過C++資料型別
- Android NDK開發中java資料型別與C/C++資料型別的對應關係AndroidJava資料型別C++
- C#型別詳解C#型別
- C++ 單例類别範本(詳解)C++單例
- C++ 資料算數型別C++型別