branchOrNOt
branchOrNOt

Reputation: 139

Python set decimal precision

I'm writting a small code for encode with arithmetic encoding. I need to set a determinate precision but I must be doing something wrong. This is the code :

def encode(string, probabilities):
    getcontext().prec = 28
    start = 0.0
    width = 1.0
    for ch in string:
        d_start, d_width = probabilities[ch]
        start += d_start*width
        width *= d_width  
    return random.uniform(start, start + width)

As I've read in the python documentation getcontext().prec should set the precision I'm willing to work with. After some iterations, d_start and d_with is very small ( ~ e^-20 ) and the variables start and width stay with the same valor from that moment on.

If further information is needed please don't hesistate asking for it.

Thanks in advance

Edit 1: Proper indentation of the code

Edit 2: I've made a print of d_start after each sum to show what I mean by saying "and the variables start and width stay with the same valor from that moment on. "

Here you have the results:

0.0
0.16
0.224
0.224
0.22784
0.22784
0.2280448
0.22812672
0.22812672
0.2281316352
0.2281316352
0.228131897344
0.228132002202
0.228132002202
0.228132008493
0.228132008493
0.228132008829
0.228132008963
0.228132008963
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971
0.228132008971

Upvotes: 4

Views: 1313

Answers (1)

Serge Ballesta
Serge Ballesta

Reputation: 148910

The problem is that getcontext().prec is only used for decimal.Decimal variables... and you define start and width as float.

You should force usage of Decimal, for example that way (assuming a from decimal import *)

def encode(string, probabilities):
    getcontext().prec = 28
    start = Decimal('0.0')
    width = Decimal('1.0')
    for ch in string:
        d_start, d_width = probabilities[ch]
        start += Decimal(d_start)*width
        width *= Decimal(d_width)
    return random.uniform(float(start), float(start + width))

Upvotes: 5

Related Questions