思维导图:
目录
1.浮点数 :
1.1浮点数家族:
浮点数家族包括float(单精度浮点型)类型,double型(双精度浮点型)以及long double三种。其中float型的数据是保留到小数点后六位的,double型是保留到小数点后15位的(详情可以通过float.h查看)。
2.例子:
#include<stdio.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的值为:%f\n",*pFloat);
return 0;
}
这段代码会打印什么结果呢?
现在来看看:
挺奇怪的一些数据是吧,那这是为什么呢?
其实这里的原因就是因为整型变量和浮点型变量两者的储存方式不一样。
3.浮点型变量的存储规则及结果分析:
3.1浮点型变量的存储规则:
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
(-1)^S * M * 2^E
(-1)^S表示符号位,当S=0,V为正数;当S=1,V为负数。
M表示有效数字,大于等于1,小于2。
2^E表示指数位。
举一个简单的例子:比如说要存一个数叫作5.0:
先找出5.0的二进制表达式: 101.0(后面的几位有效的数字)
浮点型存储表达:(-1)^0*1.01*2^2
在这里:S=0,M=1.01,E=2。
3.2浮点型在内存里的存储方式:
在这里我们来看看浮点型数据在内存里的存储:
当计算机是32位浮点数时:
最高的一位是S位,只占一个比特位。后面八个是E位占八个比特位。最后面的23个是M位占23个比特位。(-1)^S*M*2^E.(永远记住有效数字是大于1小于2的)
64位浮点数:符号位仍然只有1比特,指数位增加到了11比特,有效数字位更是增加到了52比特。
特殊规则:
1.对于有M
前面说M的范围是大于等于1小于2的,所以M=1.xxxxxxx。
在这里计算机在存数据时就耍了点高明的小伎俩:
在存储时省略掉最前面的1,在读取时再见这个1自动加上。通过这个操作,计算机就能存24
个数据了。
2.对于指数位E
1.首先,E是一个无符号的数字。E的范围;0~255。也就是E不可能是一个负数,
但是指数又是可以出现负数的,所以E在计算时会自动的加上0~255的中间数——127(当E是11个比特位时就加上1023)。
比如:2^10,指数是10,那就要写成137(32位表示)。也就是:10001001
多说无益,直接上例子分析一波:
3.分析:
int main()
{
int n = 9;
//9的二进制:0 00000000 0000000 00000000 00001001
float* pFloat = (float*)&n;
printf("n的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);
//浮点型形式:S=0,E=-126,M=0.0000000000000000001001,
//*pFloat=(-1)^0*0.0000000000000000001001*2^-126
//->*pFloat=0.000000
*pFloat = 9.0;
printf("num的值为:%d\n", n);
printf("*pFloat的值为:%f\n", *pFloat);
//*pFloat=1001.0=(-1)^0*1.001*2^3;
//->S=0,E=3+127=130,M=.001(第一个1要被抛弃)
//->二进制:0 10000010 0010000000000000000001
//->十进制:1091567616
return 0;
}