python實現float/double的0x轉化

來源:互聯網
上載者:User

標籤:tput   cte   uri   儲存方式   -fpic   div   tps   else   sdn   

1. 問題引出

最近遇到了一個小問題,即:

讀取文字檔的內容,然後將檔案中出現的數字(包括double, int, float等)轉化為16進位0x儲存

原本以為非常簡單的內容,然後就著手去寫了python,但是寫著寫著發現不對:

python貌似沒辦法直接讀取記憶體資料;
因此不得不藉助於C語言,這樣又引出了python如何調用C lib

開始寫c發現又有問題了:

int 類型的資料和float/double資料在記憶體中的儲存方式是不同的

因此花了一些力氣解決了這些問題,成功得將數字轉化為了16進位0x的儲存類型,特記錄一下,以備後續查詢,也可以讓有需要的童鞋有個參考。

2. 基本知識

完成本實驗前,你必須具備以下的基礎知識:

1). float/double在記憶體中的儲存方式

浮點數在記憶體中的儲存形式為二進位的科學計數法,即


其中,S為符號,P為階碼,F為尾數
其長度如下表所示:

? 總長度 符號 階碼 尾數
float 32 bit 1 8 23
double 64 bit 1 11 52


符號位 S: 0代表正數,1代表負數
階碼位 P: 為unsigned, 計算時候,需要將實際尾數減去7F, 即實際計算用的P=eb-0x7F
尾數位 F: 用二進位科學計演算法表示後,去掉前面的恒定1,只保留小數點後的位元據

例1:32bit二進位 0x42 0xOA 0x1A 0xA0 轉化為十進位浮點數

符號位:S=0,0x42的最高位為0
階碼位:0x42<<1=0x84, 0x84-0x7F = 5
尾數位:0x0A1AA0為換算為十進位然後小數點前加1得到1.0789375

計算:1.0789375*2^5 = 34.526

例2:將十進位數50.265轉化為32位規格化的浮點數

N = 50.265
S = 0
N/2^P = 1.xxx, 因此,P=5
F=N/2^P=50.265/32=1.57078125
由以上可知:
符號位S=0
eb = P+0x7F=0x84
尾數d[2]d[1]d[0]= 0x490F5C

因此,最終結果為:0x42490F5C (記住eb需要移位哦)

2). python如何調用C lib

簡單起見,可參考該部落格:http://blog.csdn.net/golden1314521/article/details/44055523
詳細內容可參考python官方文檔:https://docs.python.org/2/library/ctypes.html

3. 代碼

I. C 代碼:讀取float所在的記憶體位址

/* *Filename: ftoc.c */ #define uchar unsigned char#define uint unsigned intvoid ftoc(float fl, uchar arr[]) {    void *pf;    pf = &fl;    uchar i;    for(i=0; i<4; i++)    {        arr[i] = *((uchar *)pf+i);    }    return ;}

II. 編譯此代碼為libftoc.so

gcc -shared -Wl,-soname,libftoc -o libftoc.so -fPIC ftoc.c
  • shared: 表示需要編譯為動態庫(.so)
  • Wl: 告訴編譯器將後面的參數傳遞給連結器
  • soname: 指定了動態庫的soname(簡單共用名稱,Short for shared object name)

    更加詳細的介紹可參考:http://blog.csdn.net/zhoujiaxq/article/details/10213655

  • o : output,即要編譯成目標檔案的名字
  • fPIC: 地址無關代碼(.so必須加此參數),詳情可自行搜尋

III. python 代碼

#!/usr/bin/pythonimport osimport ctypeslib_name = ‘./libftoc.so‘   #我自己的 c libfilename = "rd.txt"f1 = open(filename, ‘r‘)f2 = open(‘result.txt‘, ‘w+‘)#-----------------------------------#check the number is float or notdef is_float(s):    try:        float(s)        return True    except ValueError:        pass#-----------------------------------def ftoc(num):    number = ctypes.c_float(num) #covert the python type to c type    arr = ctypes.c_ubyte * 4    parr = arr(ctypes.c_ubyte(), ctypes.c_ubyte(), ctypes.c_ubyte(), ctypes.c_ubyte())  #create a c-type(unsigned char)  array    #access the c lib    lib_ftoc = ctypes.CDLL(lib_name)    #call the c lib function!!!    #after this function, parr contains float‘s dec_number*4    lib_ftoc.ftoc(ctypes.c_float(num), parr)        lst=[]    for i in range(4):        lst.append(parr[i])        lst[i] = hex(lst[i])[2:]    #get rid of ‘0x‘        if(len(lst[i]) < 2):            lst[i] = ‘0‘+lst[i]     #make data 8-bit    string = lst[3]+lst[2]+lst[1]+lst[0]    string = string.upper()         #uppercase the characters    return string#============================================# main flow#===========================================lst = []line = f1.readline()while line:    line.strip(‘\n‘)    lst = line.split()    for i in range(len(lst)):        #if the number is digit        if lst[i].isdigit():            lst[i] = hex(int(lst[i]))            lst[i] = lst[i][2:]         #get rid of ‘0x‘             lst[i] = lst[i].upper()                 if(len(lst[i]) < 8):                lst[i] = ‘0‘*(8-len(lst[i])) + lst[i]        #if the number is float        else:             if is_float(lst[i]):                lst[i] = ftoc(float(lst[i]))    for i in range(len(lst)):        f2.write(lst[i])        f2.write(‘ ‘)    f2.write(‘\n‘)        line = f1.readline()f2.write(‘\n‘)f1.close()f2.close()

VI. 運行結果

運行前的文檔:


運行後的結果輸出:

python實現float/double的0x轉化

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.