Math.sign()
Math.sign(x) number · Added in vES6 · Updated March 13, 2026 · Math Math.sign() returns the sign of a number, indicating whether the value is positive, negative, zero, or NaN. It’s the quickest way to determine which direction a value points on the number line.
Syntax
Math.sign(x)
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
x | number | — | The number to evaluate |
Return Value
| Input | Return Value |
|---|---|
| Positive number | 1 |
| Negative number | -1 |
0 (positive zero) | 0 |
-0 (negative zero) | -0 |
NaN | NaN |
Why -0 Matters
The negative zero (-0) is a subtle but important edge case in JavaScript. While it behaves identically to 0 in most operations, it has distinct behavior in certain mathematical contexts:
// Basic comparisons treat them as equal
0 === -0; // true
0 > -1; // true
// But Object.is() distinguishes them
Object.is(0, -0); // false
Object.is(-0, -0); // true
Object.is(NaN, NaN); // true
// Division behavior differs
1 / 0; // Infinity
1 / -0; // -Infinity
In physics engines and game development, preserving the sign of zero matters when calculating velocity, direction, or forces—it can determine whether an object moves left versus right, or whether a force pushes up versus down.
Examples
Basic usage
Math.sign(5); // 1
Math.sign(-5); // -1
Math.sign(0); // 0
Math.sign(-0); // -0
Math.sign(NaN); // NaN
// Works with non-integers too
Math.sign(3.14); // 1
Math.sign(-2.71); // -1
Determining movement direction
In game development, Math.sign() cleanly determines which direction an entity should move:
function updateVelocity(currentPos, targetPos) {
const direction = Math.sign(targetPos - currentPos);
// direction = 1 (move right), -1 (move left), or 0 (already there)
const speed = 5;
return currentPos + direction * speed;
}
// Player at x=10, moving toward x=25
updateVelocity(10, 25); // returns 15
// Player at x=20, moving toward x=5
updateVelocity(20, 5); // returns 15 (actually moves left due to direction)
Handling edge cases: -0, 0, and NaN
When working with user input or computed values, explicitly handle all return cases:
function getDirectionLabel(value) {
const sign = Math.sign(value);
if (sign === 1) return 'positive';
if (sign === -1) return 'negative';
if (Object.is(sign, -0)) return 'negative zero';
if (sign === 0) return 'positive zero';
return 'not a number'; // NaN case
}
getDirectionLabel(42); // 'positive'
getDirectionLabel(-10); // 'negative'
getDirectionLabel(0); // 'positive zero'
getDirectionLabel(-0); // 'negative zero'
getDirectionLabel(NaN); // 'not a number'
getDirectionLabel(Infinity); // 'positive'
Normalizing vector components
In physics simulations, use Math.sign() to normalize direction while preserving axis information:
function applyForce(velocity, forceX, forceY) {
return {
x: velocity.x + forceX,
y: velocity.y + forceY
};
}
function clampVelocity(velocity, maxSpeed) {
const speedX = Math.sign(velocity.x) * Math.min(Math.abs(velocity.x), maxSpeed);
const speedY = Math.sign(velocity.y) * Math.min(Math.abs(velocity.y), maxSpeed);
return { x: speedX, y: speedY };
}
const player = { x: -50, y: 25 };
clampVelocity(player, 30);
// { x: -30, y: 25 } - preserves direction, caps speed
Math.sign() vs Manual Checks
// Using Math.sign() - concise and handles all cases
const sign = Math.sign(value);
// Manual if/else approach - more verbose
let sign;
if (value > 0) sign = 1;
else if (value < 0) sign = -1;
else sign = Object.is(value, -0) ? -0 : 0; // Handle -0 specially
// Ternary approach - can't distinguish 0 from -0
const sign2 = value > 0 ? 1 : value < 0 ? -1 : 0;
// This returns 0 for BOTH 0 and -0!
Math.sign() is cleaner than manual checks and is the only built-in way to reliably detect -0.
See Also
- math::trunc - Truncate decimal
- object::is — Compare values including -0