TheAlgorithms/Python · error · ValueError
Input must be a positive number.
Error message
Input must be a positive number.
What it means
Raised by fast_inverse_sqrt() in maths/fast_inverse_sqrt.py when the input number is <= 0. The function implements the Quake III fast inverse square root via bit-level struct reinterpretation, and the magic-constant trick is only meaningful for positive, finite IEEE-754 floats; zero and negatives have no real inverse square root.
Source
Thrown at maths/fast_inverse_sqrt.py:39
>>> fast_inverse_sqrt(4)
0.49915357479239103
>>> fast_inverse_sqrt(4.1)
0.4932849504615651
>>> fast_inverse_sqrt(0)
Traceback (most recent call last):
...
ValueError: Input must be a positive number.
>>> fast_inverse_sqrt(-1)
Traceback (most recent call last):
...
ValueError: Input must be a positive number.
>>> from math import isclose, sqrt
>>> all(isclose(fast_inverse_sqrt(i), 1 / sqrt(i), rel_tol=0.00132)
... for i in range(50, 60))
True
"""
if number <= 0:
raise ValueError("Input must be a positive number.")
i = struct.unpack(">i", struct.pack(">f", number))[0]
i = 0x5F3759DF - (i >> 1)
y = struct.unpack(">f", struct.pack(">i", i))[0]
return y * (1.5 - 0.5 * number * y * y)
if __name__ == "__main__":
from doctest import testmod
testmod()
# https://en.wikipedia.org/wiki/Fast_inverse_square_root#Accuracy
from math import sqrt
for i in range(5, 101, 5):
print(f"{i:>3}: {(1 / sqrt(i)) - fast_inverse_sqrt(i):.5f}")
View on GitHub (pinned to f5988cc097)
Solutions
- Guard inputs: skip or clamp values <= 0 before calling (e.g. treat 0 magnitude as a special case).
- Use max(number, 1e-12) style epsilon flooring when near-zero magnitudes are expected.
- For exact (rather than approximate) results use 1 / math.sqrt(number), which still requires number > 0.
- Validate data upstream so zero/negative magnitudes never reach the routine.
Example fix
# before
inv_len = fast_inverse_sqrt(x*x + y*y) # raises when vector is (0, 0)
# after
mag_sq = x*x + y*y
if mag_sq <= 0:
inv_len = 0.0
else:
inv_len = fast_inverse_sqrt(mag_sq) Defensive patterns
Strategy: validation
Validate before calling
if number <= 0:
raise ValueError(f'fast_inverse_sqrt requires positive input, got {number}')
result = fast_inverse_sqrt(number) Type guard
def is_positive_finite(x: object) -> bool:
import math
return isinstance(x, (int, float)) and math.isfinite(x) and x > 0 Try / catch
try:
y = fast_inverse_sqrt(x)
except ValueError:
y = 0.0 # degenerate vector / non-positive magnitude fallback Prevention
- Special-case zero-magnitude vectors before normalizing.
- Use abs() or squared magnitudes so sign errors cannot reach the function.
- Floor magnitudes with a small epsilon when near-zero inputs are expected.
When it happens
Trigger: Calling fast_inverse_sqrt(0), fast_inverse_sqrt(-1), or fast_inverse_sqrt(-0.5). The `if number <= 0` guard raises ValueError before the struct pack/unpack bit hack runs.
Common situations: Normalizing zero-length vectors (1/sqrt(0) is infinite), passing unnormalized sensor data containing zeros, sign errors when squaring/absolute values are omitted, or feeding NaN-adjacent computed magnitudes into graphics or physics code.
Related errors
- factorial_recursive() not defined for negative values
- n is negative
- power is negative
- surface_area_cube() only accepts non-negative values
- surface_area_cuboid() only accepts non-negative values
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/4e017b12d0c68721.
Report an issue: GitHub.