Python: weird rounding behavior of math.sqrt()
Question: Using Python 2.7.10, I have found quite by accident that 5*math.sqrt(3) and
math.sqrt(5**2*3) are not the same float:

    
    
    import math
    import decimal
    
    print decimal.Decimal(5*math.sqrt(3))
    print decimal.Decimal(math.sqrt(5**2*3))
    print 5*math.sqrt(3) == math.sqrt(5**2*3)
    

returns

    
    
    8.660254037844385521793810767121613025665283203125
    8.6602540378443872981506501673720777034759521484375
    False
    

which shows that they differ on the 15th decimal place. Intriguingly, this
does not happen for numbers neighboring 5 and 3. The following code show a few
pairs of numbers for which the equality fails:

    
    
    for j in range(1,10+1):
        for i in range(1,10+1):
            a = i*math.sqrt(j)
            b = math.sqrt(i**2*j)
            if not(a == b):
                print [i,j],
    

The list of problematic [i,j] pairs include: [3, 2] , [6, 2] , [9, 2] , [5, 3]
, [9, 3] , [10, 3] , [3, 6] , [6, 6] , [7, 6] , [3, 8] , [6, 8] , [9, 8] , [5,
10] , [7, 10] , [10, 10]... Any ideas on why the rounding breaks, and why
precisely for these pairs, and not others?


Answer: This is because floating point arithmetic is tricky. Neither of your results
is actually correct. They have rounding issues because of the floating point
and it looks weird because it's not rounding on powers of 10 but powers of 2.

If you need arbitrary precision arithmetic, you can use the mpmath module like
this:

    
    
    from mpmath import *
    
    mp.dps=50
    mp.pretty = True
    sqrt3 = fmul(5, mp.sqrt(3))
    sqrt75 = mp.sqrt(fmul(power(5,2), 3))
    print "5*sqrt(3) =    ", sqrt3
    print "sqrt(5**2*3) = ", sqrt75
    

That gives:

    
    
    5*sqrt(3)    =  8.6602540378443864676372317075293618347140262690519
    sqrt(5**2*3) =  8.6602540378443864676372317075293618347140262690519
    

[The link provided by Rad Lexus](http://stackoverflow.com/questions/588004/is-
floating-point-math-broken) is a good read on this topic.

