32为操作系统中float型的数是4个字节(32位),小数0.002122二进制格式如下:
00111011000010110001000101000001
左起第1位:是整个数的符号位,0正 1
负左起第2-9位:是指数的倒数
左起10-32位:是科学计数法系数的小数部分 (二进制表示)
下面是我写的一个解析float内存结构的函数,python3写的
##文件名:decimal.py
#输入32个01组成的二进制字符串
def decimals( dat):
lendat = len(dat)
if lendat != 32:
print('字符串长度不是32')
return 0
for c in dat:
if (c != '0') and (c != '1'):
print('输入的字符串含有不合法的字符')
return 0
#dattemp = dat[24:32]+dat[16:24]+dat[8:16]+dat[0:8] #写到硬盘上的浮点数要调整顺序 顺序颠倒
dattemp = dat
print('dattemp:',dattemp)
sigbit = dattemp[0] #符号位
expsigbit = dattemp[1] #指数符号位
exponent = dattemp[2:9] #指数
mantissa = dattemp[9:32] #尾数
print(sigbit,expsigbit,exponent,mantissa)
print('总长度:',(len(sigbit)+len(expsigbit)+len(exponent)+len(mantissa)))
iexp = 0 #指数的十进制
print('符号位sigbit:',sigbit)
print('指数符号位expsigbit:',expsigbit)
print('指数exponent:',exponent)
print('尾数mantissa:',mantissa)
ipos = 0 #游标 标记'1'的位置
#[expsigbit+dattemp] 就是原来原小数(二进制数)转换成科学计数法后 (样子像这样:1.1001101*2^n) 那个2上面的指数n
temp = exponent[::-1]
for c in temp:
if (c == '1') ^ (expsigbit == '0'): #右移时算'0'的个数 左移时算'1'的个数 不移不算
iexp += 2**ipos
#print('当iops=',ipos,'时,iexp=',iexp,' c:',c,'expsigbit:',expsigbit)
ipos += 1
else:
if expsigbit == '1':#如果是左移 位数值要加1
iexp += 1
iexp *= -1
#print("得到标志:",iexp)
iexp *= -1 #这里乘以-1是为了下面的好算,这就是指数了
#print("指数为",iexp)
decimalpart = 0.0 #科学计数法的小数部分
ipos = 0 #游标 标记'1'的位置
for c in mantissa:
ipos += 1
if c=='1':
decimalpart += 2**-ipos
#print('decimalpart=',decimalpart,'/t2^-',ipos,'=',2**-ipos)
intpart = 1 #整数部分 因为2进制的数科学计数法 整数部分只能是1
#print('decimalpart:',decimalpart)
if sigbit == '0':
flt = (intpart + decimalpart)*2**(iexp)
else:
flt = (-1)*(intpart + decimalpart)*2**(iexp)
return flt
################################
#文件名:main.py
#调用方法如下:
from decimal import *
s='00111011000010110001000101000001'
print('原始字符串为:',s)
print('解析结果为:',decimals(s))
解析结果为: 0.00212200009264
小数的结果不完全等于原来的小数 因为浮点数有误差 (尾数段不够长,double的长一些所以更精确)