常见的浮点型:3.14159 IE10
浮点数包括:float, double, long double。
浮点数表示的范围:float.h中定义。
浮点型存储例子:
#include <stdio.h>
int main()
{
int num = 9;
float *pFloat = (float *)#
printf("num的值为 %d:\n",num);
printf("*pFloat的值为 %f:\n",*pFloat);
*pFloat = 9.0;
printf("num的值为 %d:\n",num);
printf("*pFloat的值为 %f:\n",*pFloat);
return 0;
}
运行结果:
num和*pFloat在内存中明明就是同一个数,为什么浮点数和整数的解读结果会差别这么大?要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法。
2.在讨论浮点数之前,先看一下整数在计算机内部是怎么表示的。
int num = 9;
上面这条命令,声明了一个整形变量,类型为int,值为九(二进制写法为1001),普通的32位计算机,用四个字节表示int变量,所以九就被保存为 00000000 00000000 00000000 00001001,写成十六进制就是0x00000009。那么为什么0x00000009还原成浮点型就成了0.000000?
3.根据国际标准IEEE754,任意一个二进制浮点数V可以表示成下面形式:
V = (-1)^s*M*2^E(s是符号,M是有效数字,E是阶乘)
(1).(-1)*s表示符号位,当s=0,V为正数;当s=1,V为负数。
(2).M表示有效数字,大于等于1,小于2。
4.E为一个无符号整数(unsigned int ).这意味着如果E为8位,他的取值范围为0-255;如果E为11位,他的取值范围为0-2047,但是我们知道,科学记数法中可以出现负数,所以IEEE规定,存入内存中的E的真实值必须在加上一个真实值必须在加上一个中间数,对于8位的E,这个中间数是127;对于11位数这个中间数是1022,比如,2^10的E是10,所以保存为21位浮点数时必须保存为10+127=137,即10001001。
然后E还可以在分为三种情况:
(1)E不全为0或不全位1.
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127(或1023),得到真实值,再将有效数字M前加上第一位的1.
比如:0.5的二进制形式为0.1,规定正数部分必须为1,将小数点右移1位,则为1.0*2^(-1)其阶码为-1+127=126,表示01111110,而尾数1.0去掉正数部分为0,补齐0到23位为00000000000000000000000,则二进制表示形式为
0 01111110 00000000000000000000000
(2)E全为0.
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数,这样做是为了表示+-0,以及接近的0的很小的数字。
(3)E全为1.
这时,如果有效数字M全为0,表示+-无穷大(正负取决于符号位s);如果有效数字M不全为0,表示这个数不是一个数(NaN).
5.所以我们之前的0x00000009还原成浮点数,就成了0.0000000,首先,将0x00000009拆分,得到第一个符号位s=0,后面的8位指数E=00000000,最后23位的有效数字M=000 0000 0000 0000 0000 1001。
由于指数E全为0,所以符合上一节的第二种情况,因此浮点数V就写成 V=(-1)^0x0.00000000000000000001001x2^(-126)=1.01x2^(-146)
显然,V是一个很小的接近于0的正数,所以用十进制小数表示就是0.000000。