準確詳解: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位。
相關文章
- C語言中關於float、double、long double精度及數值範圍理解C語言
- C/C++中各種型別int、long、double、char表示範圍(最大最小值)C++型別
- c++ 基本資料型別(int、float、double、long、long long)最大值,最小是表示方法C++資料型別
- int/double資料範圍
- 資料型別範圍資料型別
- C C++變數型別大小和範圍C++變數型別
- java double、float型別的比較Java型別
- Java面試官:兄弟,你確定double精度比float低嗎?Java面試
- C++讀二進位制檔案 及 C++設定double精度C++
- C/C++——求下面資料型別的最大值和最小值: char, short, int, long, float, double, long double和numeric_limits使用C++資料型別MIT
- C++基本資料型別及型別轉換C++資料型別
- C++引用型別詳解C++型別
- 開發中遇到的float double精度問題
- Double型別精度問題引起的錯誤型別
- Java個人學習筆記-資料型別及取值範圍Java筆記資料型別
- C++資料型別C++資料型別
- c語言中%f輸出double型和float型值C語言
- C++ 使用者輸入與資料型別詳解:建立基本計算器及變數型別C++資料型別變數
- 關於MYSQL中FLOAT和DOUBLE型別的儲存MySql型別
- 【C++注意事項】1 資料型別及型別轉換C++資料型別
- C++之string型別詳解C++型別
- 【C++】資料型別-列舉型C++資料型別
- 微控制器中的資料型別佔用空間及取值範圍資料型別
- C++/C高階資料型別C++資料型別
- C++ 表示式中的型別轉換C++型別
- C++檢視資料型別C++資料型別
- [JAVA] Java 變數、表示式和資料型別詳解Java變數資料型別
- Java浮點數float,bigdecimal和double精確計算的精度誤差問題總結JavaDecimal
- PHP基礎-資料型別-floatPHP資料型別
- Double型別數值相加導致精度缺失問題型別
- C++的那些事:資料與型別C++型別
- C#資料型別及其轉換詳解C#資料型別
- C++ Lambda 表示式使用詳解C++
- C++基本資料型別總結C++資料型別
- C語言 int,float,double整型和浮點型資料在相互運算時bug原因C語言
- c++ 16進位制資料轉doubleC++
- float和double有什麼區別?
- MySQL 中 整數型別的儲存和範圍計算過程詳解MySql型別