创造网站,网站搭建合作协议,二级学院英语网站建设通知,企业管理培训课程班本章概述 本章引要练习 浮点数的存储浮点数的取出小补充题目解析彩蛋时刻#xff01;#xff01;#xff01; 本章引要
常见的浮点数#xff1a;3.1415#xff0c;1E10等。其中#xff0c;1E10是科学计数法的形式#xff0c;它也就等于1*10^10。小数数据类型#xff1… 本章概述 本章引要练习 浮点数的存储浮点数的取出小补充题目解析彩蛋时刻 本章引要
常见的浮点数3.14151E10等。其中1E10是科学计数法的形式它也就等于1*10^10。小数数据类型float ,double ,long double。
练习
在开讲本章内容前大家先来看个代码大家先猜一下结果
#define _CRT_SECURE_NO_WARNINGS 1
#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(n的值为%d\n, n);printf(*pFloat的值为%f\n, *pFloat);return 0;
}
结果运行图 不知道大家猜对多少个答案最起码要猜对两个答案吧。
浮点数的存储
在上面的代码中n和*pFloat指的是同一个空间里面的数据但是两者取出来的数据差别很大。说明两者的存储和取出数据的方式差别很大整形的数据存储咱们已经讲过了现在来讲一下浮点数的存储方式。 根据国际标准IEEE(电气和电子工程协会)754任意一个二进制浮点数V可以表示成下面的形式 举个例子
// 5.5 的二进制表示形式 101.1
小数点前面 1*2^20*2^11*2^0
小数点后面 1*2^-1
小数就为1*2^20*2^11*2^01*2^-1
我们知道2^-1为0.5.
所以小数点前面都是2的非负整数次方小数点后面都是负整数次方。小数存储的格式并不是我们所写的 101.1这个格式而是按照上面的IEE754标准进行存储的。按照这个标准写的格式为-10 * 1.011* 22。其实就是个科学计数法的表现形式 。那么按照上面的标准表示的话S0 ,M1.011 ,E2。在内存中我们浮点数存储的有价值的数据就是S ,M和E。
IEEE754标准规定如下 对于32位的浮点数32位机器平台最高的1位存放的是符号位S紧跟着8位存储的是指数位E再紧跟着的23位存储的有效值M。对于64位的浮点数64位机器平台最高的1位存放的是符号位S紧跟着11位存储的是指数位E在紧跟着52位存储的是有效值M。如图所示的存储图 IEEE754标准对E和M有些特殊规定 M的特殊规定由IEEE754标准规定1M2也就是说所有的浮点数有效值位M必须是 1.xxxxxxx。其中 .xxxxx是小数位。IEEE754标准规定在计算机中对于有效值位M只存储小数部分整数部分的1省略不进行存储当读取数据的时候再把1给加上。这样做可以扩大小数的存储范围使存储的精度增高。E的特殊规定由IEEE754标准规定的指数E是一个无符号整数unsigned char类型因为在浮点数的存储中只有一个符号位没有第二个符号位所以除了高位1位的符号位剩下的全是数值位——E为无符号整形。在32位平台下的取值范围为0~255在64位平台下的取值范围为0 ~2047.但是我们知道科学计数法中的指数是有负数的。比如
0.5 的二进制表示 0.1
IEEE754标准形式-1^0*1* 2^-1
这个时候指数E就是负数 -1为了符合科学计数的表现形式IEEE754标准规定存入内存时E的真实值必须再加上一个中间数对于32位平台这个中间数是127对于64位平台这个中间数是1023。比如32位平台2^10E为10我们存储的是E127137即10001001.
浮点数的取出
我们存储的是S,E和M所以我们直接取出这三个值就OK了。然后再按照IEEE754标准还原为小数就可以得到我们想要的值了。对于S和M这俩值的取出没什么特别的正常取出就OK了其中别忘了取出M值的时候加上1.这里最特别的值是E它的取值就要分三种情况讨论了如下
E不全为1或不全为0我们取出E的值后再减去12732位平台或者减去1023(64平台)才能得到真正的指数E上面讲过了E的存储。比如0.5的存储。
0.5的二进制位 0.1
IEEE745的形式-1^0*1.0*2^-1 s0 ,m1.0 ,E-1127126
0 01111110 00000000000000000000000 (小数部分全是0)E全为0当E的存储全为0的时候IEEE745规定原本的E1-127-12632位平台或E1-102364位平台。这个时候有效值M不在加1这样做是为了表示0或接近0的很小很小的小数。如下所示。
0 00000000 00100000000000000000000E全为1这个时候说明这个小数是个很大很大的数。(正负取决于符号位S如下所示
0 11111111 0010000000000000000000小补充
前面咱们举的小数都是较容易表示二进制的。假如我们举个较难表示的小数5.54
5.5还是比较容易表示的 101.1
但是0.04要怎样表示呢2^-2结果是0.25比0.04大太多了2^-3结果是0.125 比0.04大。………………从上面的例子中我想告诉大家的是浮点数在内存中是无法精确存储的。所以对于那些较难表示的小数计算机会在后面多输出几位或着四舍五入以便接近你想要的数据。
题目解析
上面讲了很多的知识铺垫了咱们也该回归开头的那个练习题了。。
int n9;
float *pFloat (float *)n;
printf(*pFloat的值为%f\n,*pFloat);
9的存储 00000000 00000000 00000000 00001001
当执行到这个代码的时候 printf(*pFloat的值为%f\n,*pFloat);就会把9的存储格式
当成小数的存储格式数据类型的意义S E M
即 0 00000000 0000000000000000000100
是E全为0的情况有效值M不再加1所以是个接近0的小数又因为在32位平台下输出小数点后6位
所以输出结果0.000000
//----------------------------------------//
*pFloat 9.0;printf(num的值为%d\n,n);9.0的存储格式 1001.0-1^0*1.0010*2^3 E3127130S E M0 10000010 00100000000000000000000
执行到这个代码的时候 printf(num的值为%d\n,n);就会被当成有符号整数数据类型的意义
即 01000001 00010000 00000000 00000000 (正整数原码反码和补码相同)
输出结果1091567616彩蛋时刻 https://www.bilibili.com/video/BV1Zd4y1A7yc/?spm_id_from333.337.search-card.all.clickvd_source7d0d6d43e38f977d947fffdf92c1dfad 每章一句感到累的时候请抬头看看天空。感谢你能看到这里点赞关注收藏转发是对我最大的鼓励咱们下期见