浮点型在内存中的存储
int n=9;
float* pfloat=(float*)&n;
printf("n的值为%d\n",n);
printf("n的值为%f\n",*pfloat);
* pfloat= 9.0;
printf("n的值为 %d \n",n);
printf("* pfloat的值为:%f",* pfloat);
n的值为9
n的值为0.000000
n的值为 1091567616
* pfloat的值为:9.000000
为什么会出现这种情况,这是因为在内存中 浮点数 和 整形数 遵循着不同的存储法则
首先我们先了解一下IEEE754标准
对于这个概念我们首先有一个大概的了解,下面将剩下的内容翻译为人话大致是
v =(-1)^S *M * 2^E
1. (-1)^S表示符号位 ,当s=0,v正,s=1,v负
2. M代表有效数字,大于 1 小于2
3 2^E 表示指数位
以9.0为例
// 9.0
// 1001.0
// (-1)^0 * 1.001 * 2^3
// S=0 M- 1.001 E=3
IEEE754 规定
(1) 因为 M均可表示为 大于1小于2的数字, 所在存储中对于 小数点前一位的1省略,可以提高一位精度表示
(2) 而对于 E 而言 ,首先E是一个无符号数, 当E为8位时 取值范围为0-255 ;当E为11位时取值范围为0 - 2047.
但是 对于科学计数法表达形式, 指数可负 ,
所以 IEEE754规定,存入内存中的E需要加上一个中间量来保证它的非负性,
对于 8位的E,中间值为 127; 对于11位的E,这个中间数是1023;
例如 2^10 , 存储的值 = 10+127=137 即为 10001001
//float a=5.5;
// 101.1
// (-1)^0 * 1.011^2^2
// S=0 M=1.011 E=2
//0 10000001 01100000000000000000000
(2 +127)
// 在内存化为16进制更为普遍 0x40b00000
而E 取出来时又分为三种情况
当E不为全0或不为全1时,如上图单精度,指数E-127得到真实值 ,M加上1取出即为真实值
当E为全0时,这是对于它已经加上127后得到的结果,1.xxx*2^-127 几乎接近于0,所以
直接 规定指数等于1-127(1-1023即为真实值,有效位数M不再加上第一位的1,而是还原为0.xxx的小数,其实就是表示0
当E为全1时,表示正负无穷大的情况
int n=9;
// 00000000 00000000 00000000 00001001
float* pfloat=(float*)&n;
printf("n的值为%d\n",n);
printf("n的值为%f\n",*pfloat);
// 0 00000000 00000000000000000001001
//(-1)^0*0.00000000000000000001001* 2 ^(-126)
// %f 打印 小数点后六位 0.000000
* pfloat= 9.0;
// 1001.0
//(-1)^0 * 1.001*2^3
// 0 10000010 00100000000000000000000
printf("n的值为 %d \n",n);
//01000001000100000000000000000000 正数的原反补相同 转化成2进制即可得到结果
printf("* pfloat的值为:%f",* pfloat);