文章目录
一、例题
想想看,输出的结果是什么?
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; }
二、浮点数在内存中存储方式
2.1国际标准IEEE(电气和电子工程协会)754规定:
- IEEE二进制浮点数算术标准(IEEE 754):是20世纪80年代以来最广泛使用的浮点数运算标准,为许多CPU与浮点运算器所采用。
- IEEE 754规定了四种表示浮点数值的方式:单精确度(32位)、双精确度(64位)、延伸单精确度(43比特以上,很少使用)与延伸双精确度(79比特以上,通常以80位实现)。
- 以上内容来自于百度百科。
- 简单点来说:一个任意的二进制浮点数A可以表示成下面的形式:
- (-1)^S * M * 2^E
2.s=(-1)^S,s表示的是符号位,当s=0时,A为正数;当s=1时,A为负数;- M表示有效数字,1 <= M < 2;
- 2^E表示指数位;
举个例子:
- 十进制的11.0,写成二进制为:1011.0,相当于1.011x2^3;
- 那么按照上面的形式:s=0,M=1.011,E=3;
- 而十进制的-11.0,写出二进制为:-1011.0,相当于-1.011x2^3;此时,s=1,M=1.011,E=3;
2.2实际上,浮点数在内存的存储形式为:
- IEEE 754规定:
对于32位的单精度浮点数而言,最高的1位是符号位s,接着的8位是指数E,剩下的23位为有效数字M。- 即:
2.3具体M和E是怎么算的呢?
实际上:
前面说过,1<= M < 2,也就是说,M可以写成:1.xxxx的形式,其中xxxx表示小数部分。
IEEE754规定:计算机内部保存M时,默认这个数的第一位是1,因此可以被舍去,只保留后面的小数部分;比如对二进制1.011来说,只保存.011,等到读取是,再在小数点前加1;这样做的目的是节省了1位有效数字。以单精度浮点数(32bit)来说,留给M的只有23位,将第一位1舍去后,等于可以保存24位有效数字;对于指数E:
(1)E作为一个无符号整数,这意味着,如果E为8位(单精度浮点数),它的取值范围为:0-255;如果E为11位(双精度浮点数),它的取值为:0-2047;
(2)但是,科学记数法中,指数位是可以为负数的,所以**IEEE 754规定:E存入内存时,必须在加上一个中间数,对于单精度浮点数来说,这个数是127,对于双精度浮点数来说,这个数是1023;
例如:2^10,E为10,保存在内存中时为:10+127=137,即写成二进制为:1000 1001;然后指数E从内存中取出还可以分为三种情况:
1.E不全为0或者全为1:
这时,浮点数就采用下面规则表示,即指数E的计算值减去127(或者1023)得到真实值,在将真实值得有效数字M前加上第一位1,即得到二进制数;
例如:
十进制:0.5(1/2) 的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移动1位,为:1.0*2^(-1),其E为:-1+127=126,表示为:0111 1110,而M为:1.0去掉整数部分1,为0,补齐到23位为:00000000000000000000000;
则这个数的二进制在内存中保存形式为:
0 0111110 00000000000000000000002. E全为0
这时,浮点数的指数E等于1-127(或者1-1023)即为真实值,
有效数字M不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于
0的很小的数字。3. E全为1
这时,如果有效数字M全为0,表示±无穷大(正负取决于符号位s);
三、题解
3.1刚开始的例子答案
3.2详细解析
- n的值为:9;
解:n=9为int类型, float* pFloat = (float*)&n;的含义是使用float类型指针pFloat指向n的地址并把n的地址强制转换为float*,此时,n的值并没有改变,只是加了一个指针指向它,所以接下来以整型打印整型9;- *pFloat的值为0.000000;
解:
(1)整型9的在内存的表示形式为:00000000 00000000 00000000 00001001
(2)而计算机以浮点数来读取整型时,会把首位0看成s,后面8位0会看成E的值,最后23位00000000000000000001001 看成有效值M;
(3)那么这就符合E的取值全为0这种情况,此时有效值非常接近0;所以打印为浮点型0.000000;- num 的值为::1091567616;
解:
(1)此时n的值已经被指针*pFloat修改为浮点型:9.0;
(2)浮点型9.0形式为:(-1^0 * 1.001 * 2^3
(3)s=0 ; E 等于3 +127 = 130 ; M = 1.001 ,有效值为001;
(4)9.0在内存的存储形式为:0 1000 0010 001 00000000000000000000
(5)而以整型%d的形式打印此时的浮点型,就得:
- *pFloat的值为9.000000;
解:
此时就很简单了,因为n的值已经被指针修改为浮点型9.0,那么此时以浮点型%f来打印浮点型9.0,得到的值当然为9.000000;
四、感谢与预告
- 如果本文对你有所帮助,麻烦你点个赞加收藏,你的支持就是小编更新的最大动力,非常感谢!
- 预告下一篇文章:⑤指针的归纳and详解;