先复习一下十进制和二进制转换的知识点,以及小端大端的知识点:
十进制数与二进制数的转换
http://course.cug.edu.cn/21cn/电子技术/resource/knowledge/zsd11/z1103.htm
小端大端:
http://biancheng.dnbcw.info/1000wen/352749.html
部分参考文章:
http://www.360doc.com/content/12/0228/12/6973384_190241745.shtml
http://www.linuxidc.com/Linux/2012-07/65986.htm
十进制小数转换二进制算法
http://bbs.csdn.net/topics/340219944
int(32bit):
内容 SNNN NNNN NNNN NNNN NNNN NNNN NNNN NNNN
float(32bit):
内容 SEEE EEEE EMMM MMMM MMMM MMMM MMMM MMMM
float ( 32bit ) S E*08 M*23
double ( 64bit ) S E*11 M*52
S 表示符号位: 0-正 1-负
N 表示int的二进制位
E 表示指数位
M表示尾数
举个例子,比如 -12.5 怎么表示?
编码过程:
其实就是求解S、E、M是什么,下面分别来进行计算:
1. 求S:
首先根据观察,因为是负数所以 S=1
2. 求E:
12.5分成两部分来进行计算:整数 + 小数 = 12 + 0.5,整数部分除二取余,小数部分乘二取整
12的二进制表示为:1100
0.5的二进制表示为:0.1
将两者加起来,得到12.5的二进制为:1100.1
将小数点移动到第一个有效数字后面 1100.1 -> 1.1001 方向是向左移动 移动了3位
向左移动三位,所以对应的E = 127 + 3 = 130 = 10000010
3. 求 M:
刚才得到的移动小数点之后的二进制为:1.1001,因为第一位永远是1,所以可以忽略掉,于是得到 .1001
所以M = 1001,补零为: M = 1001000 00000000 00000000
根据刚才所求得的S、E、M,组合可以得到最终的float存储方法为:
S = 1
E = 1000001 0
M = 1001000 00000000 00000000
S E M = 11000001 01001000 00000000 00000000
解码过程:
其实就是通过各位对应汉语提取出S、E、M是什么,下面分别来进行计算:
1. 取S:
首先根据观察,取第1位的数字,得到1,1代表负数,所以最终结果需要乘以 -1
2. 取E:
应为该float是32bit的,所以[2~9]位表示E,得到E = 1000001 0
E = ( 10000010 )b = 130
二进制指数为:130 - 127 = 3
3. 取 M:
取[10-32]位,得到 M = 1001000 00000000 00000000,转变成小数为:1.1001
根据1.1001和二进制指数为3,所以小数点向右移动3位,得到:1100.1
所以无符号原数的二进制形式为:1100.1,变为十进制计算方法为:
1*2^3 + 1*2^2 + 0*2^1 + 0*2^1 + 1*2^(-1) + 0*2^(-2) + ... + 0^2^(-20) = 8 + 4 + 0.5 = 12.5
举个特殊例子,0 怎么表示?
注意,浮点数为0时,S=0,E=0,M=0
验证以上理论是否正确?
测试完全一致!