目录
一、存储准则
根据国际标准IEEE(电气和电子工程协会) 754,任意一个二进制浮点数V可以表示成下面的形式:
- (-1)^S * M * 2^E
- (-1)^s表示符号位,当s=0,V为正数;当s=1,V为负数。
- M表示有效数字,大于等于1,小于2。
- 2^E表示指数位。
二:浮点数的存储与读取方式
(一)将浮点数存储进内存
S:正数就是(-1)^0,负数则是(-1)^1。
M:M一定属于 [1,2) ,M中小数点前面必然是1,因此1存储在内存中无意义 (如果把1存储进内存反而多占了一位,会降低所保存数字的精度) 。其实只需要在内存中保存小数点后面的几位数字即可。
E:IEEE规定为E开辟的空间只可以存储无符号整数,但是实际上E却可能是负数,比如0.5。因此IEEE规定E的真实值必须加上一个中间值(8位的E中间值为127,11位的为1023),在读取这个浮点数时又重新减去再减去中间值。
(二)将浮点数从内存中拿出
1.E不全为0或者不全为1
S:直接拿出。
M:从内存中拿出后在前面加上1和小数点
E:减去中间值。
2.E全为0
E:E = 1-127 = -126(或者1-1023)
M:M前面不加1而是加0。
这样实际上是为了表示+-0与接近于0的很小的数字。
3.E全为1
S:直接拿出。
M:从内存中拿出后在前面加上1和小数点
E:减去中间值。
如果有效数字M全为0,表示±无穷大(正负取决于符号位s)
三、图解与举例
四、代码练习
练习题
底下这个代码输出结果是什么呢?
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; }
答案
n的值为:9
*pFloat的值为:0.000000
num的值为:1091567616
*pFloat的值为:9.000000
请看下面解析
#include<stdio.h> #include<stdlib.h> int main() { int n = 9; //00000000000000000000000000001001 正数原码=反码=补码 //0 00000000 00000000000000000001001 //S E M\ //E全为0,直接用1-127=-126 //M = 0.00000000000000000001001 //S = 0 //(-1)^0 * 0.00000000000000000001001 * 2^(-126) //0.0000000000…………(很小的数字) // float *pFloat = (float *)&n; printf("n的值为:%d\n", n);//9 printf("*pFloat的值为:%f\n", *pFloat);//0.0000000000…………(很小的数字) *pFloat = 9.0; //9.0 //1001.0 //1.001 * 2^3 //(-1)^0 * 1.001 * 2^3 //存取 //S = 0 //M = 1.001 //E = 3 //E = 3 +127 = 130 //0 10000010 00100000000000000000000 //本来以浮点数打印是没有问题的,但是这里却要求我们用整数的形式打印。 //01000001000100000000000000000000 //直接将这个二进制转换成十进制的整数 //1,091,567,616 printf("num的值为:%d\n", n);//1,091,567,616 printf("*pFloat的值为:%f\n", *pFloat);//9.0 system("pause"); return 0; }
最后,浮点数的存储规则,你理解了吗?
有什么问题可以私信我哦,我们可以一起探讨。