Search code examples
pythonmathsqrt

How do I calculate square root in Python?


I need to calculate the square root of some numbers, for example √9 = 3 and √2 = 1.4142. How can I do it in Python?

The inputs will probably be all positive integers, and relatively small (say less than a billion), but just in case they're not, is there anything that might break?


Note: This is an attempt at a canonical question after a discussion on Meta about an existing question with the same title.

Related


Solution

  • Option 1: math.sqrt()

    The math module from the standard library has a sqrt function to calculate the square root of a number. It takes any type that can be converted to float (which includes int) and returns a float.

    >>> import math
    >>> math.sqrt(9)
    3.0
    

    Option 2: Fractional exponent

    The power operator (**) or the built-in pow() function can also be used to calculate a square root. Mathematically speaking, the square root of a equals a to the power of 1/2.

    The power operator requires numeric types and matches the conversion rules for binary arithmetic operators, so in this case it will return either a float or a complex number.

    >>> 9 ** (1/2)
    3.0
    >>> 9 ** .5  # Same thing
    3.0
    >>> 2 ** .5
    1.4142135623730951
    

    (Note: in Python 2, 1/2 is truncated to 0, so you have to force floating point arithmetic with 1.0/2 or similar. See Why does Python give the "wrong" answer for square root?)

    This method can be generalized to nth root, though fractions that can't be exactly represented as a float (like 1/3 or any denominator that's not a power of 2) may cause some inaccuracy:

    >>> 8 ** (1/3)
    2.0
    >>> 125 ** (1/3)
    4.999999999999999
    

    Edge cases

    Negative and complex

    Exponentiation works with negative numbers and complex numbers, though the results have some slight inaccuracy:

    >>> (-25) ** .5  # Should be 5j
    (3.061616997868383e-16+5j)
    >>> 8j ** .5  # Should be 2+2j
    (2.0000000000000004+2j)
    

    (Note: the parentheses are required on -25, otherwise it's parsed as -(25**.5) because exponentiation is more tightly binding than negation.)

    Meanwhile, math is only built for floats, so for x<0, math.sqrt(x) will raise ValueError: math domain error and for complex x, it'll raise TypeError: can't convert complex to float. Instead, you can use cmath.sqrt(x), which is more more accurate than exponentiation (and will likely be faster too):

    >>> import cmath
    >>> cmath.sqrt(-25)
    5j
    >>> cmath.sqrt(8j)
    (2+2j)
    

    Precision

    Both options involve an implicit conversion to float, so floating point precision is a factor. For example let's try a big number:

    >>> n = 10**30
    >>> x = n**2
    >>> root = x**.5
    >>> root == n
    False
    >>> root - n  # how far off are they?
    0.0
    >>> int(root) - n  # how far off is the float from the int?
    19884624838656
    

    Very large numbers might not even fit in a float and you'll get OverflowError: int too large to convert to float. See Python sqrt limit for very large numbers?

    Other types

    Let's look at Decimal for example:

    Exponentiation fails unless the exponent is also Decimal:

    >>> decimal.Decimal('9') ** .5
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unsupported operand type(s) for ** or pow(): 'decimal.Decimal' and 'float'
    >>> decimal.Decimal('9') ** decimal.Decimal('.5')
    Decimal('3.000000000000000000000000000')
    

    Meanwhile, math and cmath will silently convert their arguments to float and complex respectively, which could mean loss of precision.

    decimal also has its own .sqrt(). See also calculating n-th roots using Python 3's decimal module