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.