浮点数转化为机器二进制码

    科技2022-07-13  159

    浮点数二进制表示

    浮点数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位

    转化为机器码

    def t2bin(length,x): if x>0: S='0' else: x=-x S='1' x1=int(x) #取整数部分,之后转化为二进制 i=0 x2='' #储存小数二进制 flag=0 #标志小数位连续为0 sum0=0 #表示小数位连续为0的个数 f_len=length[1] e_len=length[0] while(x%1!=0 and i!=length[2]): 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 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**(e_len-1)-1)[2:].rjust(e_len,'0') print(S+exp+frac) int_x=int(S+exp+frac,2) print(hex(int_x)) f=[8,23,23] #分别代表exp,frac位数和默认精度 d=[11,52,52] t2bin(f,0.5) t2bin(d,-0.5) t2bin(f,0.005) t2bin(d,-0.005) t2bin(f,11.28125) t2bin(d,11.28125)

    float转化机器码python算法

    已测试代码中的几个数据

    #先求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) #0x41348000

    double转机器码python算法

    def double_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=52 #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**10-1)[2:].rjust(11,'0') print(S+exp+frac) int_x=int(S+exp+frac,2) print(hex(int_x)) float_bin(-0.5,52) 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) #0x41348000

    https://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) #0x41348000

    https://blog.csdn.net/ganxingming/article/details/1449526

    https://baike.baidu.com/item/规格化浮点数/4044919?fr=aladdin

    Processed: 0.014, SQL: 8