2014-09-12 36 views
1

我正在實施Arithmetic Encoder & Decoder。它的一個子模塊涉及將定點值轉換爲二進制,反之亦然。從二進制字符串檢索定點值

要編碼的字符串相當長,因此我必須考慮很多精度= 250。一旦我有一個Decimal值;它正在轉換爲二進制字符串(def decimal_to_binary_str)。問題是要從二進制文件def binary_str_to_decimal中檢索Decimal值。有人能指出這個問題嗎?

import decimal 

def decimal_to_binary_str(f, l): 
    res = "" 
    var = f - int(f) 
    while var != 0 and len(res) < l: 
     var = var*2 
     res += '{0:.250f}'.format(var)[0] 
     var = var - int(var) 
    return res 

def binary_str_to_decimal(bit_str): 
    a = decimal.Decimal(0) 
    b = decimal.Decimal(1) 
    res = decimal.Decimal(0.5) 

    for j in bit_str: 
     if j == '0': 
      b -= (b-a)/2 
      res = res - (b-a)/2 
     elif j == '1': 
      a += (b-a)/2 
      res = res + (b-a)/2 
    return res 

if __name__ == "__main__": 
    decimal.setcontext(decimal.Context(prec=250)) 
    f = decimal.Decimal('0.2157862006526829178278743649908677246339070461540076509576931506281654871337287537411826845238756634211771470806684727059082493570941004017476336218118077112203256327565095923853074403357680122784788435203804147809638828466085270584355766316314164101') 
    print f 
    b = decimal_to_binary_str(f, 669) 
    print binary_str_to_decimal(b) 


    ''' 
    I have marked with pipe symbol(|) the difference in what is retrieved and what was the original. 
    Output: 
0.215786200652682917827874364990867724633907046154007650957693150628165487133728753741182684523875663421177147080668472705908249357094100401747633621811807711220325632756509592385307440335768012278478843|5203804147809638828466085270584355766316314164101 
0.215786200652682917827874364990867724633907046154007650957693150628165487133728753741182684523875663421177147080668472705908249357094100401747633621811807711220325632756509592385307440335768012278478843|3376547904539139004978887353289003223234434034223 
    ''' 
+0

「小數」實際上是固定點,而不是浮點數。 – 2014-09-12 22:24:50

+0

已修改。謝謝! – ajmartin 2014-09-12 22:32:18

+0

你如何處理像'decimal.Decimal('0.1')'' – 2014-09-12 22:42:11

回答

1

的問題是與decimal_to_binary_str功能。在699位之後停止該功能時,將截斷信息。信息丟失是您將其轉換回十進制時看到的內容。你可以清楚地看到這一點,如果你有不同的輸出長度玩:

f = decimal.Decimal('0.31') 
out = decimal_to_binary_str(f, 64) 
print binary_str_to_decimal(out) 
Out: 0.30999999999999999997506335003283339801782858557999134063720703125 
out = decimal_to_binary_str(f, 128) 
print binary_str_to_decimal(out) 
Out: 0.310000000000000000000000000000000000000411423022787800627789057788027785987236532944870230632528063097197446040809154510498046875 
out = decimal_to_binary_str(f, 256) 
print binary_str_to_decimal(out) 
Out: 0.31000000000000000000000000000000000000000000000000000000000000000000000000000293629730873211117263135963335213585417944

它從來沒有真正收斂到原來的數目。找到一個十進制數的二進制表示形式是一個複雜的問題。查看IEEE 754標準和相似的標準。