Math.hypot()
Returns the square root of the sum of squares of its arguments, without intermediate overflow.
Math.hypot()
Math.hypot(value1)
Math.hypot(value1, value2)
Math.hypot(value1, value2, /* …, */ valueN)- Added in JavaScript ES2015
Parameters
| Parameter | Type | Description |
|---|---|---|
$value1, …, valueNoptional | number | Numbers whose squares are summed. Any count of arguments is accepted, including none. |
Return value
numberThe square root of the sum of squares of the given arguments. Returns Infinity if any argument is ±Infinity (even if another is NaN), NaN if any argument is or converts to NaN, and 0 if no arguments are given or all are ±0.
Math.hypot() computes √(v₁² + v₂² + … + vₙ²). Reach for it whenever you need the length of a vector or the distance between two points: the difference of the coordinates goes in, the distance comes out, in any number of dimensions.
Why not just Math.sqrt()
The hand-rolled Math.sqrt(a*a + b*b) squares each value first, so it overflows to Infinity once a value passes about 1e154, and underflows to 0 for very small values — even though the true answer is perfectly representable. Math.hypot() scales internally and survives both extremes. Below those limits the two agree to within a rounding step, so the built-in is the safer default.
Special cases
Infinity wins over NaN: Math.hypot(NaN, Infinity) is Infinity, because the magnitude is infinite regardless of the unknown component. Sign is discarded — with one argument the result equals Math.abs(). Arguments are coerced with Number(), so numeric strings work but a non-numeric string yields NaN.
Performance
That extra safety costs cycles. In a tight hot loop over ordinary-sized coordinates — particle systems, collision checks — the manual sqrt form is measurably faster, and comparing squared distances avoids the square root entirely.
Example
When to use it
- Measure the distance between two points on a canvas or grid
- Get the magnitude of a velocity or force vector in a physics step
- Compute the modulus of a complex number stored as {re, im}
- Normalize an RGB or n-dimensional vector to unit length
Frequently asked questions
What is the difference between Math.hypot() and Math.sqrt()?
Math.hypot() squares and sums its arguments for you and does so without intermediate overflow, while Math.sqrt(a*a + b*b) computes the squares in double precision first and returns Infinity or 0 when those intermediates fall outside the representable range. For ordinary magnitudes both give the same answer, and the manual form is faster.
How do I calculate the distance between two points in JavaScript?
Pass the coordinate differences to Math.hypot(): Math.hypot(x2 - x1, y2 - y1). The same call extends to three dimensions by adding z2 - z1 as a third argument, and to any dimension by spreading an array of differences.
Why does Math.hypot() with no arguments return 0?
An empty sum of squares is 0, and its square root is 0, so Math.hypot() returns 0 rather than NaN. This makes spreading an empty array of coordinates safe, but it also means an accidentally empty argument list looks like a real zero-length result.
More examples
Surviving overflow
The manual form squares 1e200 into Infinity and 1e-200 into 0, printing Infinity and 0. Math.hypot() returns the correct 1.414213562373095e+200 and 1.414213562373095e-200 because it rescales before squaring.
const big = 1e200;
console.log(Math.hypot(big, big));
console.log(Math.sqrt(big * big + big * big));
const tiny = 1e-200;
console.log(Math.hypot(tiny, tiny));
console.log(Math.sqrt(tiny * tiny + tiny * tiny));NaN and Infinity precedence
Infinity beats NaN and yields Infinity; an ordinary NaN argument still poisons the result. Arguments go through Number(), so "5" counts as 5 while "four" becomes NaN. All-zero arguments give a positive 0.
console.log(Math.hypot(NaN, Infinity));
console.log(Math.hypot(NaN, 3));
console.log(Math.hypot(3, 4, "5"));
console.log(Math.hypot(3, "four"));
console.log(Math.hypot(0, -0));Normalizing a vector
Dividing each component by the magnitude gives [0.6, 0.8], whose own hypot is 1. The zero-length guard matters: without it every component would become NaN.
function normalize(v) {
const len = Math.hypot(...v);
return len === 0 ? v.map(() => 0) : v.map((n) => n / len);
}
const unit = normalize([3, 4]);
console.log(unit);
console.log(Math.hypot(...unit)); // back to length 1
console.log(normalize([0, 0]));
Discussion