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?

**Related**

- Integer square root in python
- Is there a short-hand for nth root of x in Python?
- Difference between **(1/2), math.sqrt and cmath.sqrt?
- Why is math.sqrt() incorrect for large numbers?
- Python sqrt limit for very large numbers?
- Which is faster in Python: x**.5 or math.sqrt(x)?
- Why does Python give the "wrong" answer for square root? (specific to Python 2)
- calculating n-th roots using Python 3's decimal module
- How can I take the square root of -1 using python? (focused on NumPy)
- Arbitrary precision of square roots

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

·
Santiago Trujillo

```
>>> import numpy as np
>>> np.sqrt(25)
5.0
>>> np.sqrt([2, 3, 4])
array([1.41421356, 1.73205081, 2. ])
```

For negative reals, it'll return `nan`

, so `np.lib.scimath.sqrt()`

is available for that case.

```
>>> a = np.array([4, -1, np.inf])
>>> np.sqrt(a)
<stdin>:1: RuntimeWarning: invalid value encountered in sqrt
array([ 2., nan, inf])
>>> np.lib.scimath.sqrt(a)
array([ 2.+0.j, 0.+1.j, inf+0.j])
```

Another option, of course, is to convert to complex first:

```
>>> a = a.astype(complex)
>>> np.sqrt(a)
array([ 2.+0.j, 0.+1.j, inf+0.j])
```

·
Santiago Trujillo
Report

Depending on your goal, it might be a good idea to delay the calculation of square roots for as long as possible. SymPy might help.

SymPy is a Python library for symbolic mathematics.

```
import sympy
sympy.sqrt(2)
# => sqrt(2)
```

This doesn't seem very useful at first.

But sympy can give more information than floats or Decimals:

```
sympy.sqrt(8) / sympy.sqrt(27)
# => 2*sqrt(6)/9
```

Also, no precision is lost. (√2)² is still an integer:

```
s = sympy.sqrt(2)
s**2
# => 2
type(s**2)
#=> <class 'sympy.core.numbers.Integer'>
```

In comparison, floats and Decimals would return a number which is very close to 2 but not equal to 2:

```
(2**0.5)**2
# => 2.0000000000000004
from decimal import Decimal
(Decimal('2')**Decimal('0.5'))**Decimal('2')
# => Decimal('1.999999999999999999999999999')
```

Sympy also understands more complex examples like the Gaussian integral:

```
from sympy import Symbol, integrate, pi, sqrt, exp, oo
x = Symbol('x')
integrate(exp(-x**2), (x, -oo, oo))
# => sqrt(pi)
integrate(exp(-x**2), (x, -oo, oo)) == sqrt(pi)
# => True
```

Finally, if a decimal representation is desired, it's possible to ask for more digits than will ever be needed:

```
sympy.N(sympy.sqrt(2), 1_000_000)
# => 1.4142135623730950488016...........2044193016904841204
```

·
Santiago Trujillo
Report

**Disclaimer:** this is for a more specialised use-case. This method might not be practical in all circumstances.

Benefits:

- can find integer values (i.e. which
**integer**is the root?) - no need to convert to float, so better precision (can be done that well too)

I personally implemented this one for a crypto CTF challenge (RSA cube root attack),where I needed a precise integer value.

The general idea can be extended to any other root.

```
def int_squareroot(d: int) -> tuple[int, bool]:
"""Try calculating integer squareroot and return if it's exact"""
left, right = 1, (d+1)//2
while left<right-1:
x = (left+right)//2
if x**2 > d:
left, right = left, x
else:
left, right = x, right
return left, left**2==d
```

As @wjandrea have also pointed out, **this example code can NOT compute **. This is a side-effect of the fact that it does not convert anything into floats, so no precision is lost. If the root is an integer, you get that back. If it's not, you get the biggest number whose square is smaller than your number. I updated the code so that it also returns a bool indicating if the value is correct or not, and also fixed an issue causing it to loop infinitely (also pointed out by @wjandrea). This implementation of the general method still works kindof weird for smaller numbers, but above 10 I had no problems with.

For smaller numbers, you can just use all the other methods from other answers. They generally use floats, which *might* be a loss of precision, but for small integers that should mean no problem at all. All of those methods that use floats have the same (or nearly the same) limit from this.

If you still want to use this method and get float results, it should be trivial to convert this to use floats too. Note that that will reintroduce precision loss, this method's unique benefit over the others, and in that case you can also just use any of the other answers. I think the newton's method version converges a bit faster, but I'm not sure.

For larger numbers, where loss of precision with floats come into play, this method can give results closer to the actual answer (depending on how big is the input). If you want to work with non-integers in this range, you can use other types, for example fixed precision numbers in this method too.

Currently, and afaik, the only other answer that has similar or better precision for large numbers than this implementation is the one that suggest SymPy, by Eric Duminil. That version is also easier to use, and work for any kind of number, the only downside is that it requires SymPy. My implementation is free from any huge dependencies if that is what you are looking for.

·
Santiago Trujillo
Report

Python's `fractions`

module and its class, `Fraction`

, implement arithmetic with rational numbers. The `Fraction`

class doesn't implement a square root operation, because most square roots are irrational numbers. However, it can be used to approximate a square root with arbitrary accuracy, because a `Fraction`

's numerator and denominator are arbitrary-precision integers.

The following method takes a positive number `x`

and a number of iterations, and returns upper and lower bounds for the square root of `x`

.

```
from fractions import Fraction
def sqrt(x, n):
x = x if isinstance(x, Fraction) else Fraction(x)
upper = x + 1
for i in range(0, n):
upper = (upper + x/upper) / 2
lower = x / upper
if lower > upper:
raise ValueError("Sanity check failed")
return (lower, upper)
```

See the reference below for details on this operation's implementation. It also shows how to implement other operations with upper and lower bounds (although there is apparently at least one error with the `log`

operation there).

- Daumas, M., Lester, D., Muñoz, C., "Verified Real Number Calculations: A Library for Interval Arithmetic", arXiv:0708.3721 [cs.MS], 2007.

·
Santiago Trujillo
Report

Most simple and accurate way to compute square root is Newton's method.

You have a number which you want to compute its square root (`num`

) and you have a guess of its square root (`estimate`

). Estimate can be any number bigger than 0, but a number that makes sense shortens the recursive call depth significantly.

```
new_estimate = (estimate + num/estimate) / 2
```

This line computes a more accurate estimate with those 2 parameters. You can pass `new_estimate`

value to the function and compute another `new_estimate`

which is more accurate than the previous one or you can make a recursive function definition like this.

```
def newtons_method(num, estimate):
# Computing a new_estimate
new_estimate = (estimate + num/estimate) / 2
print(new_estimate)
# Base Case: Comparing our estimate with built-in functions value
if new_estimate == math.sqrt(num):
return True
else:
return newtons_method(num, new_estimate)
```

For example we need to find 30's square root. We know that the result is between 5 and 6.

```
newtons_method(30,5)
```

number is 30 and estimate is 5. The result from each recursive calls are:

```
5.5
5.477272727272727
5.4772255752546215
5.477225575051661
```

The last result is the most accurate computation of the square root of number. It is the same value as the built-in function `math.sqrt()`

.

*This answer was originally posted by gunesevitan, but is now deleted.*

·
Santiago Trujillo
Report

This variation uses string manipulations to convert a string which represents a decimal floating-point number to an `int`

, calls `math.isqrt`

to do the actual square root extraction, and then formats the result as a decimal string. `math.isqrt`

rounds down, so all produced digits are correct.

The input string, `num`

, must use plain float format: 'e' notation is not supported. The `num`

string can be a plain integer, and leading zeroes are ignored.

The `digits`

argument specifies the number of decimal places in the result string, i.e., the number of digits after the decimal point.

```
from math import isqrt
def str_sqrt(num, digits):
""" Arbitrary precision square root
num arg must be a string
Return a string with `digits` after
the decimal point
Written by PM 2Ring 2022.01.26
"""
int_part , _, frac_part = num.partition('.')
num = int_part + frac_part
# Determine the required precision
width = 2 * digits - len(frac_part)
# Truncate or pad with zeroes
num = num[:width] if width < 0 else num + '0' * width
s = str(isqrt(int(num)))
if digits:
# Pad, if necessary
s = '0' * (1 + digits - len(s)) + s
s = f"{s[:-digits]}.{s[-digits:]}"
return s
```

```
print(str_sqrt("2.0", 30))
```

```
1.414213562373095048801688724209
```

For small numbers of digits, it's faster to use `decimal.Decimal.sqrt`

. Around 32 digits or so, `str_sqrt`

is roughly the same speed as `Decimal.sqrt`

. But at 128 digits, `str_sqrt`

is 2.2× faster than `Decimal.sqrt`

, at 512 digits, it's 4.3× faster, at 8192 digits, it's 7.4× faster.

Here's a live version running on the SageMathCell server.

·
Santiago Trujillo
Report