Skip to main content

How to Calculate Square Root of Negative Numbers in Python

By default, calculating the square root of a negative value using the standard math library raises a ValueError: math domain error. This is because real number mathematics doesn't define square roots for negatives. To handle this, you need complex numbers using Python's specialized modules.

Single Values with cmath​

The cmath (complex math) module is part of the standard library and returns complex results when appropriate:

import cmath

val = -16

result = cmath.sqrt(val)

print(f"Result: {result}") # (4j)
print(f"Real part: {result.real}") # 0.0
print(f"Imaginary part: {result.imag}") # 4.0
The Imaginary Unit

Python uses j (engineering notation) instead of i to represent √-1. Access components with .real and .imag attributes.

Comparison with math Module​

import math
import cmath

# ❌ Raises ValueError
try:
math.sqrt(-16)
except ValueError as e:
print(f"math.sqrt error: {e}")

# ✅ Returns complex number
result = cmath.sqrt(-16)
print(f"cmath.sqrt result: {result}") # 4j

Output:

math.sqrt error: math domain error
cmath.sqrt result: 4j

Arrays with numpy.emath​

For NumPy arrays, regular np.sqrt() returns nan for negative values. Use np.emath.sqrt() for complex support:

import numpy as np

arr = np.array([4, -4, 25, -25])

# Regular sqrt: returns nan for negatives
regular = np.sqrt(arr)
print(f"np.sqrt: {regular}")
# [2. nan 5. nan] with RuntimeWarning

# emath: returns complex numbers
complex_result = np.emath.sqrt(arr)
print(f"np.emath.sqrt: {complex_result}")
# [2.+0.j 0.+2.j 5.+0.j 0.+5.j]

Output:

<main.py>:6: RuntimeWarning: invalid value encountered in sqrt
np.sqrt: [ 2. nan 5. nan]
np.emath.sqrt: [2.+0.j 0.+2.j 5.+0.j 0.+5.j]
Silent Failures

Regular np.sqrt() issues a RuntimeWarning but continues with nan values. This can silently corrupt your data pipeline. Use emath when negative inputs are possible.

Working with Complex Results​

import cmath

result = cmath.sqrt(-9) # 3j

# Extract components
print(f"Real: {result.real}") # 0.0
print(f"Imaginary: {result.imag}") # 3.0
print(f"Magnitude: {abs(result)}") # 3.0
print(f"Phase: {cmath.phase(result)}") # 1.5707... (π/2 radians)

# Verify: (3j)² = -9
print(f"Squared: {result ** 2}") # (-9+0j)

Output:

Real: 0.0
Imaginary: 3.0
Magnitude: 3.0
Phase: 1.5707963267948966
Squared: (-9+0j)

Creating Complex Numbers​

# Literal notation
z1 = 3 + 4j

# Using complex()
z2 = complex(3, 4)

# From square root
import cmath
z3 = cmath.sqrt(-25) # 5j

print(z1, z2, z3)

Output:

(3+4j) (3+4j) 5j

Library Comparison​

ModuleResult for √-1Use Case
math❌ ValueErrorReal numbers only
cmath✅ 1jSingle complex values
numpy🟡 nan + warningClean real-number arrays
numpy.emath✅ 1jMixed arrays with negatives

Quick Reference​

GoalMethod
Single negative sqrtcmath.sqrt(x)
Array with negativesnp.emath.sqrt(arr)
Get real partresult.real
Get imaginary partresult.imag
Get magnitudeabs(result)

Summary​

Use cmath.sqrt() for single negative values, it returns proper complex numbers instead of raising errors. For NumPy arrays with potential negative values, use np.emath.sqrt() to avoid silent nan corruption. Both modules seamlessly handle the transition between real and complex results.