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
mathValueErrorReal numbers only
cmath1jSingle complex values
numpy🟡 nan + warningClean real-number arrays
numpy.emath1jMixed 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.