一、 概念
与数学中的实数的概念差不多,在一个值的后面加上一个小数点,该值就成为一个浮点值,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 获得整数 02 0.25 *2 = 0.5 获得整数 03 0.5 *2 = 1 获得整数 14 ==> 0.125 = 0.001
十进制整数转换为二进制整数采用"除2取余,逆序排列"法。
用2去除十进制整数,可以得到一个商和余数;再用2去除商,又会得到一个商和余数,如此进行,直到商为零时为止,然后把先得到的余数作为二进制数的低位有效位,后得到的余数作为二进制数的高位有效位,依次排列起来。
1 8/2 = 4······0 获得余数 02 4/2 = 2······0 获得余数 03 2/2 = 1······0 获得余数 04 1/2 = 0······1 获得余数 15 ==> 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 010 ==> 11 0100 0001 0000 0010 0000 0000 0000 000012 0x4 1 0 2 0 0 0 0
代码验证:
1 //C 打印输出浮点型数据使用转换说明%f 2 #include3 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 12 using namespace std;13 int main()14 {15 float f = 8.125;16 unsigned int* p = reinterpret_cast (&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值