pythonmathsquare-root

Rounding ** 0.5 and math.sqrt


In Python, are either

n**0.5  # or
math.sqrt(n) 

recognized when a number is a perfect square? Specifically, should I worry that when I use

int(n**0.5)  # instead of
int(n**0.5 + 0.000000001)

I might accidentally end up with the number one less than the actual square root due to precision error?


Solution

  • Yes, you should worry:

    In [11]: int((100000000000000000000000000000000000**2) ** 0.5)
    Out[11]: 99999999999999996863366107917975552L
    
    In [12]: int(math.sqrt(100000000000000000000000000000000000**2))
    Out[12]: 99999999999999996863366107917975552L
    

    obviously adding the 0.000000001 doesn't help here either...

    As @DSM points out, you can use the decimal library:

    In [21]: from decimal import Decimal
    
    In [22]: x = Decimal('100000000000000000000000000000000000')
    
    In [23]: (x ** 2).sqrt() == x
    Out[23]: True
    

    for numbers over 10**999999999, provided you keep a check on the precision (configurable), it'll throw an error rather than an incorrect answer...