浮点数5.25
二进制可表示为 101.01
整数部分每次除以二,余数则为个,百,千位(权值位1,2,4)的二进制数,直到为0
5/2=2 余1 个位
2/2=1 余0 百位
1/2=0 余1 千位
小数部分每次乘2,个位为1则小数位为1 权值为(1/2,1/4,1/8),直到小数位为0
0.25*2=0.5 个位为0,则(1/2权值位0)
0.5*2=1 个位为1,则(1/4有权值)
表示为101.01
根据IEEE规范标准
分为三段,s(奇偶),exp(指数) , frac(基数)
浮点标准表示数 V=(-1)^s * M * 2^E三种形式,三种不同的计算方式
32位示意
数据类型有 float double 两种分别 32位 64位(4 、8字节)
浮点标准表示数
数 V=(-1)^s * M * 2^E
这个式子看起来有点复杂
但是对二进制操作却很方便(2^n其实就是小数点的移位操作)
浮点数总能表示为 1.???*2^E ,如 101.101 = 1.01101* 2^2,0.0101 = 1.01 *2^-2
正好对应M*2^E
S,M,E分别对应3段
S=s #s=0为正,1为负数 E=e-2^(k-1)+1 #代表指数段 e即为exp的值 (k就是exp的位数 8或11) #可以看出E的取值是 -2^(k-1)-1 ~ 2^(k-1) M=1+f #M大小即为1到2之间,因为f小于1 f就是 frac的值/(2^23) 23代表float位数,double为52 结果 V=(-1)^s * M * 2^E如 float 11.25 --> 1011.01 = 1.01101*2^3
s=0
E=3 e=E+2^7-1=3+127=130
M=1.01101 frac=.011010000… 补齐0到23位机器码python表示为
0 10000010 011010000… 补齐0到23位已测试代码中的几个数据
#先求E,如果整数位大于0,E直接等于整数位数减一,否则E= -(小数点后连续0的个数+1) ''' 0.5 = 0.1 = 1* 2^-1 0.25 =0.01 = 1* 2^-2 ''' def float_bin(x,y): #x为浮点数,y为小数点精度 if x>0: S='0' else: x=-x S='1' x1=int(x) #取整数部分,之后转化为二进制 i=0 x2='' #储存小数二进制 flag=0 #标志小数位连续为0 sum0=0 #表示小数位连续为0的个数 f_len=23 #frac长度 while(x%1!=0 and i!=y): x=x-int(x) x=x*2 if x<1: x2=x2+'0' if flag==0: sum0=sum0+1 else: x2=x2+'1' flag=1 i=i+1 print(S,bin(x1),x2) if x1!=0: E=len(bin(x1))-3 frac=(bin(x1)+x2)[3:].ljust(f_len,'0') else: E=-1-sum0 frac=x2[sum0+1:].ljust(f_len,'0') exp=bin(E+2**7-1)[2:].rjust(8,'0') print(S+exp+frac) int_x=int(S+exp+frac,2) print(hex(int_x)) float_bin(-0.5,23) float_bin(0.5,23) #0x3f000000 float_bin(1.5,23) float_bin(-1.5,23) #0x3fc00000 float_bin(0.005,23) #0x3ba3d700 float_bin(11.28125,23) float_bin(-11.28125,23) #0x41348000https://blog.csdn.net/ganxingming/article/details/1449526
float_bin(0.5,52) #0x3f000000 float_bin(1.5,52) float_bin(-1.5,52) #0x3fc00000 float_bin(0.005,52) #0x3ba3d700 float_bin(11.28125,52) float_bin(-11.28125,52) #0x41348000https://blog.csdn.net/ganxingming/article/details/1449526
https://baike.baidu.com/item/规格化浮点数/4044919?fr=aladdin