潘家园网站建设,个人网站导航模版,wordpress 年度归档,网站开发确认表✨个人主页#xff1a; 熬夜学编程的小林
#x1f497;系列专栏#xff1a; 【C语言详解】 【数据结构详解】
目录
1、浮点数在内存中的存储
1.1、练习
1.2、浮点数怎么转化为二进制
1.3、浮点数的存储
1.3.1、浮点数存的过程
1.3.2、浮点数取的过程
1.3、题目解析…
✨个人主页 熬夜学编程的小林
系列专栏 【C语言详解】 【数据结构详解】
目录
1、浮点数在内存中的存储
1.1、练习
1.2、浮点数怎么转化为二进制
1.3、浮点数的存储
1.3.1、浮点数存的过程
1.3.2、浮点数取的过程
1.3、题目解析
总结 1、浮点数在内存中的存储 常见的浮点数3.14159、1E10(1^10)等浮点数家族包括 float 、 double 、 long double 类型。 浮点数表示的范围 float.h 中定义 1.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(num的值为%d\n,n);printf(*pFloat的值为%f\n,*pFloat);return 0;
} 输出什么 按照我们整数存储的想法打印的结果分别是9、9.000000、9、9.000000 但是为什么会出现上面的结果呢下面就从浮点数的存储来详细讲解此代码。 1.2、浮点数怎么转化为二进制 首先我们来个简单的例子 把十进制小数5.25化为二进制小数我们应该怎么操作 我们分为以下几步 1. 以小数点为界进行拆分 2. 整数部分转为二进制相信大家肯定没问题 3. 小数部分采用的是乘2取整法当乘2之后小数部分得到0就停止计算 十进制小数5.25 1、以小数点为界进行拆分整数部分为5小数部分为0.25 2、整数转化为二进制为101 3、小数部分采取“乘2取整法”0.25*20.5整数部分为0小数部分为0.5继续乘2,0.5*21.0整数部分为1小数部分为0小数部分为0则停止计算。取的数字为整数部分数字因此转化为二进制小数为0.01。 4. 合并结果整数部分 小数部分最终得到二进制结果为101.01. 5. 二进制小数转化为十进制验算 101.011*2^20*2^11*2^00*2^-11*2^-25.25 以上就是浮点数化为二进制的步骤了下面我们来看看更复杂一点的例子 把十进制3.14化为二进制 1、以小数点为界进行拆分整数部分为3小数部分为0.14 2、整数转化为二进制为11 3、小数部分采取“乘2取整法”0.14*20.28整数部分为0小数部分为0.28继续乘2, 0.28*20.56整数部分为0小数部分为0.56继续乘2, 0.56*21.12整数部分为1小数部分为0.12继续乘2, 0.12*20.24整数部分为0小数部分为0.24.............小数部分为0则停止计算。取的数字为整数部分数字。 1.3、浮点数的存储 上面的代码中 num 和 *pFloat 在内存中明明是同⼀个数为什么浮点数和整数的解读结果会差别这么大 要理解这个结果⼀定要搞懂浮点数在计算机内部的表示方法。 根据国际标准IEEE电气和电子⼯程协会 754任意⼀个⼆进制浮点数V可以表示成下面的形式 V (−1) ^S * M ∗ 2^E • (−1)^S 表示符号位当S0V为正数当S1V为负数 • M 表示有效数字M是大于等于1小于2的 • 2^E 表示指数位 举例来说 ⼗进制的5.0写成⼆进制是 101.0 相当于 1.01×2^2 。 那么按照上面V的格式可以得出S0M1.01E2。 ⼗进制的-5.0写成⼆进制是 -101.0 相当于 -1.01×2^2 。那么S1M1.01E2。 IEEE 754规定 对于32位的浮点数最高的1位(第一位)存储符号位S接着的8位存储指数E剩下的23位存储有效数字M。 对于64位的浮点数最高的1位(第一位)存储符号位S接着的11位存储指数E剩下的52位存储有效数字M。 1.3.1、浮点数存的过程 IEEE 754 对有效数字M和指数E还有⼀些特别规定。 前面说过 1 ≤ M2 也就是说M可以写成 1.xxxxxx 的形式其中 xxxxxx 表示小数部分。 IEEE 754 规定在计算机内部保存M时默认这个数的第⼀位总是1因此可以被舍去只保存后面的 xxxxxx部分。比如保存1.01的时候只保存01等到读取的时候再把第⼀位的1加上去。这样做的目的是节省1位有效数字。以32位浮点数为例留给M只有23位将第⼀位的1舍去以后等于可以保存24位有效数字。 至于指数E情况就比较复杂。 首先E为⼀个无符号整数unsigned int。 这意味着如果E为8位它的取值范围为0~255如果E为11位它的取值范围为0~2047。但是我们知道科学计数法中的E是可以出现负数的所以IEEE 754规定 存入内存时E的真实值必须再加上⼀个中间数 对于8位的E这个中间数是127对于11位的E这个中间数是1023。比如2^10的E是10所以保存成32位浮点数时必须保存成10127137即10001001。 1.3.2、浮点数取的过程 指数E从内存中取出还可以再分成三种情况 E不全为0或不全为1 这时浮点数就采用下面的规则表示即 指数E的计算值减去127或1023 得到真实值再将 有效数字M前加上第⼀位的1。 比如0.5 的⼆进制形式为0.1由于规定正数部分必须为1即将小数点右移1位则为1.0*2^(-1)其阶码为-1127(中间值)126表示为01111110而尾数1.0去掉整数部分为0补齐0到23位 00000000000000000000000则其⼆进制表示形式为: 0 01111110 00000000000000000000000 E全为0 这时浮点数的指数E等于1-127或者1-1023即为真实值有效数字M不再加上第⼀位的1而是还原为0.xxxxxx的小数。这样做是为了表示±0以及接近于0的很小的数字。 0 00000000 00100000000000000000000 E全为1 这时如果有效数字M全为0表示±无穷大正负取决于符号位s 0 11111111 00010000000000000000000 好了关于浮点数的表示规则就说到这里。 1.3、题目解析 下面让我们回到⼀开始的练习 先看第1环节为什么 9 还原成浮点数就成了 0.000000 9以整型的形式存储在内存中得到如下⼆进制序列 0000 0000 0000 0000 0000 0000 0000 1001 首先将 9 的⼆进制序列按照浮点数的形式拆分得到第⼀位符号位s0后面8位的指数 E00000000 最后23位的有效数字M000 0000 0000 0000 0000 1001。 由于指数E全为0所以符合E为全0的情况。因此浮点数V就写成 V(-1)^0 × 0.00000000000000000001001×2^(-126)1.001×2^(-146) 显然V是⼀个很小的接近于0的正数所以用十进制小数表示就是0.000000。 再看第2环节浮点数9.0为什么整数打印是 1091567616 首先浮点数9.0 等于⼆进制的1001.0即换算成科学计数法是1.001×2^3 所以 9.0 (−1) ^0 ∗ (1.001) ∗ 2^3 那么第⼀位的符号位S0有效数字M等于001后面再加20个0凑满23位指数E等于3127130 即10000010 所以写成⼆进制形式应该是SEM即 0 10000010 001 0000 0000 0000 0000 0000 这个32位的⼆进制数被当做整数来解析的时候就是整数在内存中的补码此数为正数原反补码相同原码正是 1091567616 。 通过浮点数进行存储按照浮点数打印因此*pFloat9.000000。 总结 本篇博客就结束啦谢谢大家的观看如果公主少年们有好的建议可以留言喔谢谢大家啦