954,515 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Float accuracy

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.

LaMouche
Posting Whiz in Training
269 posts since Oct 2006
Reputation Points: 83
Solved Threads: 39
 

Consider the decimal module.

griswolf
Veteran Poster
1,165 posts since Apr 2010
Reputation Points: 344
Solved Threads: 256
 
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'
snippsat
Practically a Posting Shark
808 posts since Aug 2008
Reputation Points: 353
Solved Threads: 294
 

Thanks, I'll look into the Decimal module.

LaMouche
Posting Whiz in Training
269 posts since Oct 2006
Reputation Points: 83
Solved Threads: 39
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: