float型的數在內存中的表示 附:python3解析函數

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的長一些所以更精確)

發佈了37 篇原創文章 · 獲贊 32 · 訪問量 21萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章