Member Avatar for Mouche

Hello. I wrote a program to convert decimal fraction values into binary fractions.

I seem to be running into some floating point accuracy problems. After multiplying a floating point number by 2 over and over, eventually the number becomes corrupted. Since I'm multiplying so many times, I think the error occurs because the small inaccuracies of the floating point number eventually become significant.

original_num = 0.1575
num = original_num
digits = []
while (num != 0):
    print "%f * 2 = %f" % (num, num * 2.0),
    num *= 2.0
    if (num >= 1):
        num -= 1
        print " so 1"
        digits.append('1')
    else:
        print " so 0"
        digits.append('0')

conversion = "".join(digits)
print "\n%g is 0.%s" % (original_num, conversion)

Here is the output:

$ python binary_fractions.py
0.1575 * 2 = 0.315  so 0
0.315 * 2 = 0.63  so 0
0.63 * 2 = 1.26  so 1
0.26 * 2 = 0.52  so 0
0.52 * 2 = 1.04  so 1
0.04 * 2 = 0.08  so 0
0.08 * 2 = 0.16  so 0
0.16 * 2 = 0.32  so 0
0.32 * 2 = 0.64  so 0
0.64 * 2 = 1.28  so 1
0.28 * 2 = 0.56  so 0
0.56 * 2 = 1.12  so 1
0.12 * 2 = 0.24  so 0
0.24 * 2 = 0.48  so 0
0.48 * 2 = 0.96  so 0
0.96 * 2 = 1.92  so 1
0.92 * 2 = 1.84  so 1
0.84 * 2 = 1.68  so 1
0.68 * 2 = 1.36  so 1
0.36 * 2 = 0.72  so 0
0.72 * 2 = 1.44  so 1
0.44 * 2 = 0.88  so 0
0.88 * 2 = 1.76  so 1
0.76 * 2 = 1.52  so 1
0.52 * 2 = 1.04  so 1
0.04 * 2 = 0.08  so 0
0.08 * 2 = 0.16  so 0
0.16 * 2 = 0.32  so 0
0.32 * 2 = 0.64  so 0
0.64 * 2 = 1.28  so 1
0.28 * 2 = 0.56  so 0
0.56 * 2 = 1.12  so 1
0.12 * 2 = 0.24  so 0
0.24 * 2 = 0.48  so 0
0.48 * 2 = 0.96  so 0
0.96 * 2 = 1.92  so 1
0.92 * 2 = 1.84  so 1
0.84 * 2 = 1.68  so 1
0.68 * 2 = 1.36  so 1
0.360001 * 2 = 0.720001  so 0
0.720001 * 2 = 1.44  so 1
0.440002 * 2 = 0.880005  so 0
0.880005 * 2 = 1.76001  so 1
0.76001 * 2 = 1.52002  so 1
0.52002 * 2 = 1.04004  so 1
0.0400391 * 2 = 0.0800781  so 0
0.0800781 * 2 = 0.160156  so 0
0.160156 * 2 = 0.320312  so 0
0.320312 * 2 = 0.640625  so 0
0.640625 * 2 = 1.28125  so 1
0.28125 * 2 = 0.5625  so 0
0.5625 * 2 = 1.125  so 1
0.125 * 2 = 0.25  so 0
0.25 * 2 = 0.5  so 0
0.5 * 2 = 1  so 0

0.1575 is 0.00101000010100011110101110000101000111101011100001010001

I'm aware of the limitations of floating point arithmetic, but I don't know how I can best protect against these problems. I know some conversions to decimal continue infintely, but I would at least be able to choose how many digits it goes out to, and not have it end prematurely. Do you have any suggestions?

Thanks.

but I would at least be able to choose how many digits it goes out to, and not have it end prematurely. Do you have any suggestions?

There is no problem to control how many digits you want with decimal module use getcontext().prec or python string formatting.

>>> from decimal import *
>>> Decimal(1) / Decimal(7)
Decimal('0.142857')
>>> getcontext().prec = 2
>>> Decimal(1) / Decimal(7)
Decimal('0.14')
>>> print Decimal(1) / Decimal(7)
0.14
>>> getcontext().prec = 7
>>> Decimal(1) / Decimal(7)
Decimal('0.1428571')
>>> '%.2f' % (Decimal(1) / Decimal(7))
'0.14'
Member Avatar for Mouche

Thanks, I'll look into the Decimal module.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.