目录
1. 举例
常见的浮点数类型有:float ,double, long double
浮点数表示的范围:float.h中定义
先看一道例题:
#include<stdio.h>
#include<Windows.h>
int main(){
int n = 9;
float *pFloat = (float*)&n;
printf("n的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);
*pFloat = 9.0;
printf("num的值为:%d\n", n);
printf("*pFloat的值为:\n", *pFloat);
system("pause");
return 0;
}
2.存储规律
出现这样的结果主要由浮点型在内存中的存储有关,下面我们理解下浮点型在内存中是如何存储的 。
任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
举例来说: 十进制的5.0,写成二进制是 101.0 ,相当于 1.01×2^2 。 那么,按照上面V的格式,
可以得出s=0,M=1.01,E=2。
十进制的-5.0,写成二进制是 -101.0 ,相当于 -1.01×2^2 。那么,s=1,M=1.01,E=2。
ps:关于小数的十进制转化为二进制在文章末详细介绍
s区:用0&1来表示浮点数的符号
E区:E中存储的为无符号整数,8bit的取值范围为【0,255】;但是我们知道科学计数法的指数位是可以出现负数的,所以有规定E中 存储时必须在实值的基础上加上一个中间数127;即存储时范围为【0,255】,但实际的指数值范围为 【-127,128】
例:2^10中指数值为10 存储时保存成10+127=137,即10001001,取出时先转换为十进制再减去127得实际指数值。
M区:因为所以浮点数都可写成 1.xxxxxxxx 的形式,所以在计算机保存时会将1.舍去 只保留小数部分,在取出时加上
这样实际就有24bit的内存
s区:用0&1来表示浮点数的符号
E区:取值范围【0,2047】中间数1023 实际指数范围【-1023,1024】
M区:实际53bit内存
注:由于浮点数精度的问题,浮点数直接不可直接比较
特殊情况:E区全0:这时,浮点数的指数E等于1-127(或者1-1023)即为真实值, 有效数字M不再加上第一位的1,而是还原为
0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。
E区全1:这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s)。
3.例题讲解
回顾例题:9的二进制序列为0000 0000 0000 0000 0000 0000 0000 1001
当它被以浮点型读取时E区全为0,被读取时按0输出
9.0→1001.0→(-1^0 1.001 2^3 →S=0 E=3+127=130 M=1.001
即存储为0 10000010 001 0000 0000 0000 0000 0000
当这个二进制数以整形读取时,正是1091567616
4.小数转换为二进制数问题
整数部分:除二取余 (自下而上保留)
小数部分:乘二取整 (自上而下保留)
例:
5.为什么小数部分要乘2取整呢?
我们继续以0.125为例 0.125表示一个数里有1个1/10 2个1/100 5个1/1000
0.001表示一个数里有0个1/2 0个1/4 1个1/8
那么0.125里有多少个1/2多少个1/4多少个1/8呢
0.125/(1/2)=0 0.125/(1/4)=0 0.125/(1/8)=1
好比十进制的小数位要除10取整一样,二进制的小数位要除2取整。