浮点型包括哪些类型?
其中float、double、long double类型都属于浮点型
浮点型的存储方式
在这之前,可以先把以下代码跑一下,看看输出结果是多少?
#include<stdio.h>
int main()
{
int n =9;
float* p = (float*)&n;
printf("n = %d\n",n);
printf("*p = %f\n",*p);
*p = 9.0;
printf("n = %d\n",n);
printf("%f\n",*p);
return 0;
}
会发现输出的4个结果分别是:9,0.000000,1091567616,9.000000。
那么为什么会这样呢?说明浮点数和整数在内存中存储的方式是一定有区别的。
这要讲到C语言依照的是IEEE(电气与电子工程协会)754规定:
V=(-1)^s*M*2^E
其中V表示浮点数,M表示有效数字,s为0或1(相当于整型中二进制符号位),E为指数。
举个例子: 十进制 V=5.5。 换算成二进制为:101.1
十进制小数点后如何换算成二进制呢:小数点后是从2^-1次方开始,那0.5就是2分之1,也就是2^-1次方。
回到正题,二进制101.1的科学计数法表示为1.011*2^2。此时S=0,有效数字M=1.011,指数E=2。
那么重点来了,在内存中。
32位float类型:00000000000000000000000000000000
被拆分成3部分:0 00000000 0000000000000000000000
其中第一部分1bit存储S,第二部分8bit存储E,第三部分23bit存储M。
64位double类型:0000000000000000000000000000000000000000000000000000000000000000
被拆分成3部分:0 00000000000 00000000000000000000000000000000000000000000...
其中第一部分1bit存储S,第二部分11bit存储E,第三部分52bit存储M。
特别注意的是:第二部分存储M是不保存小数点前的1,比如刚刚的M=1.011,小数点前1不存储,因为小数点前一定是1,所以没必要存储,浪费存储空间。存储011时,要补齐23bit,后面都要补0,变成00000011
难点:至于指数E,若E为8bit,取值0~255;若E为11bit,取值0~2047。存入内存时E的真实值必须加上一个中间数。
对于8bit的E,这个中间数是127;对于11bit的E,这个中间数是1023。(取值范围的中间数)
例如刚刚的E等于2,则存放前 E=2+127;变成二进制就是10000001。
而指数E从内存中取出还分3种情况:
E不全为0或1:取E减去127(或1023)得到真实值,再将有效数字M前加上第一位1。
E全为0:默认为无限接近于0。
E全为1:这时,如果有效数字M全为0,表示无穷大(正负取决于符号位S)。
举个例子:
float f = 5.5f; s=0,M=011,E=2+127;
最后存储为:0 10000001 01100000000000000000000
十六进制为:40 b0 00 00
回到刚开始的程序:
int n = 9; 整型n的存储为00000000000000000000000000001001。
若以浮点型的形式打印:则会被分成三部分:0 00000000 00000000000000000001001。
S=0,E全为0,符合第二种情况,因此打印出来的结果为 0。
别的情况就留给读者们去思考啦~ 打了那么多字,不容易,给个赞吧!