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.0Comparison with math Module
import math
import cmath
try:
math.sqrt(-16)
except ValueError as e:
print(f"math.sqrt error: {e}")
result = cmath.sqrt(-16)
print(f"cmath.sqrt result: {result}") # 4jOutput:
math.sqrt error: math domain error
cmath.sqrt result: 4jArrays 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 = np.sqrt(arr)
print(f"np.sqrt: {regular}")
complex_result = np.emath.sqrt(arr)
print(f"np.emath.sqrt: {complex_result}")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]Working with Complex Results
import cmath
result = cmath.sqrt(-9) # 3j
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)
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
z1 = 3 + 4j
z2 = complex(3, 4)
import cmath
z3 = cmath.sqrt(-25) # 5j
print(z1, z2, z3)Output:
(3+4j) (3+4j) 5jLibrary Comparison
| Module | Result for √-1 |
Use Case |
|---|---|---|
math |
❌ ValueError |
Real numbers only |
cmath |
✅ 1j |
Single complex values |
numpy |
🟡 nan + warning |
Clean real-number arrays |
numpy.emath |
✅ 1j |
Mixed arrays with negatives |
Quick Reference
| Goal | Method |
|---|---|
| Single negative sqrt | cmath.sqrt(x) |
| Array with negatives | np.emath.sqrt(arr) |
| Get real part | result.real |
| Get imaginary part | result.imag |
| Get magnitude | abs(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.