上一章《C语言浮点数实现(一)》给大家讲解了浮点数的由来、组成以及由于浮点数导致的世界级重大事故,以提高大家对学习浮点数积极性,了解浮点数的重要性。虽说大多数场景基本上不会在意这些细节,但是难免会遇见少数场景哈!例如:某迪的底盘团队就遇见过,如果没记错的话,该问题从发现到解决总计用时接近一周左右。可能有朋友会发出疑问,迪子的研发团队如此庞大,怎么会出现这种问题?这里就给大家解释一下,这并不完全是迪子导致的问题,这是由于更换芯片后芯片平台的运算器导致的,当然,更换后的芯片仍是车规级芯片。说多了哈,若有感兴趣的朋友,可以私信我。下面就直接开始主题,小数与浮点数的互转。
目录
1、浮点数的组成
解:在《C语言浮点数实现(一)》已经详细说过了,不知道的朋友可以看看历史文章。
2、3.14159转浮点表达式实例
2.1、第一步:计算整数部分为3
数学计算:3 除以 2 = 1余1;再用1除以2 = 0余1,最后取两次余数,也就得到11;
2.2、第二步:计算小数部分为0.14159
数学计算:
0.14159*2=0.28318->取整 = 0;
0.28318*2=0.56636->取整 = 0;
0.56636*2=1.13272->取整 = 1;
0.13272*2=0.26544->取整 = 0;
0.26544*2=0.53088->取整 = 0;
0.53088*2=1.06176->取整 = 1;
0.06176*2=0.12352->取整 = 0;
0.12352*2=0.24704->取整 = 0;
…….
…….
这里就不继续运算了,篇幅太长了,而且基本上没有限制;
综上:最后得出的3.14159二进制表达为11.001001……;
2.3、获取符号位
因为3.14159是正数,所以符号位等于0;
2.4、获取阶码
转化为1.xxxxxxxxx格式
11.001001……转化为1.xxxxxxxx格式,那小数点就需要向左移1位。
即:1.1001001…*2^1
由此可得,其阶码为1 + 127,float的阶码偏移为127,1为小数点的偏移位数。
2.5、获取尾数
尾数就是1.1001001…2^1的小数部分->1001001…;
2.6、获取最终浮点数的二进制表达式
符号位(s) + 阶码(exp) + 尾数(f)
即:0 10000000(128) 1001001…;
3、0 10000001 01010000…转小数
3.1、获取符号位
0 10000001 01010000…的符号位为0,表明其值为正数。
3.2、获取阶码
0 10000001 01010000…的阶码为 100000001 ,十进制表达就是129,实际指数为129 - 127 = 2,这里表明小数点向左移动了两位。
3.3、获取尾数
0 10000001 01010000…的尾数为 0101000…。
依据第二节计算尾数的方式以及3.2节得出的实际指数,进行逆运算,计算尾数01010000…的实际尾数过程如下:
因为实际指数为2,表明小数点向左偏移两位;
所以实际尾数等于1.010100000…;
3.4、获取转换后的小数
依据1.010100000…计算规则,小数前一位乘以2^0,小数后一位乘以2^(-1)依次递减。
1*2^0 + 0*2^(-1) + 1*2^(-2) + 0*2^(-3) + 1*2^(-4) + ……..
= 1 + 0 + 1/4 + 0 +1/16 + …
= 1.3125……
最终得出1.3125...*2^(2) = 1.3125...*4 = 5.25......
4、总结
基于以上,相信大家会对小数与浮点数的互转有一定概念,这里也说下为什么不直接以3.14159进行相互举例,而是通过两组不同的数据,是因为为了体现其差异性,让大家更好的理解“阶码”这一概念。总之,通过上述的讲解,大家应该要有一个概念,浮点数的表达是无穷无尽的,而我们的float仅仅取了23位,double取了52位,所以在不同平台使用float表示其数据时,会有一定的误差,这是正常的,但是作为一名优秀的工程师,理应了解这一特性,让误差控制在自己手里,让计算机运行在自己脑子里。下章《C语言浮点数实现之注意事宜(三)-终章》将讲解使用浮点数时应需要注意的相关事项,此章可以避免很多不可思议的BUG,建议大家阅读思考一下,相信会有帮助的。
标签:阶码,尾数,浮点数,C语言,获取,实例,取整,小数 From: https://blog.csdn.net/qq_40939768/article/details/143281488