一、 概念
與數學中的實數的概念差不多,在一個值的后面加上一個小數點,該值就成為一個浮點值,C語言中浮點類型有float、double和long double;
二、書寫形式
類似於科學記數法,稱為指數記數法或E記數法,E后面的數字代表數10的指數
三、實型與整型的區別
整數沒有小數部分,浮點數有小數部分,表示的具體數字的個數相同
浮點數可以表示的范圍比整數大
在任意區間內,存在無窮多個實數,所以計算機的浮點數不能表示區間內的所有的值,表示不精確,可以試着打印輸出123456789;
通常浮點數只是實際值的近似值,7.0可能存儲為浮點值6.999999
四、浮點數在計算機內部的存儲
float 與double 類型的數據在計算機內部的表示方式相同,都分為:符號位(最高位),指數部和尾數部,因所占存儲空間不同,故所能夠表示的數值范圍和精度不同;
類型 | 符號位 | 指數部 | 尾數部 |
float | 1(第31位) | 8(第23~30位) | 23(0~22) |
double | 1(第63位) | 11(第52~62位) | 52(0~51) |
十進制小數轉換成二進制小數采用"乘2取整,順序排列"法。
用2乘十進制小數,可以得到積,將積的整數部分取出,再用2乘余下的小數 部分,又得到一個積,再將積的整數部分取出,如此進行,直到積中的小數部分為零,或者達到所要求的精度為止。 然后把取出的整數部分按順序排列起來,先取的整數作為二進制小數的高位有效位,后取的整數作為低位有效位。
1 0.125*2 = 0.25 獲得整數 0 2 0.25 *2 = 0.5 獲得整數 0 3 0.5 *2 = 1 獲得整數 1 4 ==> 0.125 = 0.001
十進制整數轉換為二進制整數采用"除2取余,逆序排列"法。
用2去除十進制整數,可以得到一個商和余數;再用2去除商,又會得到一個商和余數,如此進行,直到商為零時為止,然后把先得到的余數作為二進制數的低位有效位,后得到的余數作為二進制數的高位有效位,依次排列起來。
1 8/2 = 4······0 獲得余數 0 2 4/2 = 2······0 獲得余數 0 3 2/2 = 1······0 獲得余數 0 4 1/2 = 0······1 獲得余數 1 5 ==> 8 = 1000
五、浮點數的轉換
浮點數轉換成二進制
- 用科學記數法表示二進制浮點數
- 計算指數偏移后的值
- 注:計算指數時需要加上偏移量,偏移量的值與類型有關(float為127,double類型為1024)
1 float 8.125 = 1000.001 = 1.000001 * 2^3 2 3 符號位: 0 4 5 指數部分:3+127 = 130 = 1000 0010 6 7 小數部分:000001 8 9 0 1000 0010 0000 01 0000 0000 0000 0000 0 10 ==> 11 0100 0001 0000 0010 0000 0000 0000 0000 12 0x4 1 0 2 0 0 0 0
代碼驗證:
1 //C 打印輸出浮點型數據使用轉換說明%f 2 #include<stdio.h> 3 int main() 4 { 5 float f = 8.125; 6 unsigned int* p = (unsigned int*) &f; 7 printf(“0x%08x\n”, *p); 8 return 0; 9 } 10 //C++ 11 #include <iostream> 12 using namespace std; 13 int main() 14 { 15 float f = 8.125; 16 unsigned int* p = reinterpret_cast<unsigned int*>(&f); 17 cout << "0x" << hex << *p << endl; 18 return 0; 19 }
六、補充部分:浮點數的溢出
6.1上溢:當計算導致數字過大,超過當前類型能表達的范圍時,就會發生上溢,現代C將浮點型上溢賦予一個特殊值INF(inf)或infinity
6.2下溢:當浮點數的指數部分已經是最小值,即現有的可用位來表示最小,將該數除以2,計算機只好將尾數部分的位右移一位;以十進制為例,0.1234E-10 / 10 ==> 0.0123E-10;
6.3NaN:Not a number的縮寫,例如將給asin()函數(給定一個數值,返回一個角度,該角度的正弦值為該數值)傳遞一個大於1的數值,該函數行為未定義,該函數此時將返回一個NaN值