Math.sign()

Returns 1, -1, 0, -0, or NaN indicating the sign of a number.

Signature
Math.sign(x)
  • Added in JavaScript ES2015

Parameters

ParameterTypeDescription
$xnumberA number whose sign is returned. Non-numbers are coerced first.

Return value

number1 if x is positive, -1 if x is negative, 0 if x is positive zero, -0 if x is negative zero, and NaN otherwise.

Math.sign() reduces a number to its direction. It has five possible results, not three: 1, -1, 0, -0, and NaN.

When to reach for it

Anywhere direction matters more than magnitude. It makes a clean numeric comparator — arr.sort((a, b) => Math.sign(a - b)) — and it reads better than nested ternaries when branching on direction: scroll or swipe direction, whether a value is above or below a target, which way to step in a loop.

It also pairs with Math.abs() to build sign-preserving operations. Math.sign(x) * Math.round(Math.abs(x)) gives away-from-zero rounding; Math.sign(x) * Math.min(Math.abs(x), cap) caps a magnitude without flipping direction.

What trips people up

Zero. Math.sign(0) is 0 and Math.sign(-0) is -0, so a truthiness check like if (Math.sign(x)) treats both zeros as false — usually what you want, but not a way to distinguish them. And because 0 === -0, only Object.is() tells them apart.

The other one is coercion: Math.sign("foo") and Math.sign() return NaN rather than throwing, and NaN is neither positive nor negative, so a > 0 / < 0 branch on the result silently falls through to the else.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Writing a numeric sort comparator as Math.sign(a - b)
  • Detecting scroll or drag direction from a delta
  • Preserving a value's sign while transforming its magnitude
  • Choosing a step direction of +1 or -1 in a loop

Frequently asked questions

What does Math.sign() return?

It returns 1 for positive numbers, -1 for negative numbers, 0 for positive zero, -0 for negative zero, and NaN for anything that cannot be coerced to a number.

How do I check whether a number is positive or negative?

Use Math.sign(x) === 1 or Math.sign(x) === -1. Note that Math.sign(-0) === 0 is true because -0 === 0, so use Object.is if the zero's sign matters.

Is Math.sign() a good sort comparator?

Yes — Array.prototype.sort only looks at the sign of the returned value, so (a, b) => Math.sign(a - b) sorts numbers ascending and states the intent clearly.

More examples

As a sort comparator

sort only needs the sign of the comparator's return value, so Math.sign(a - b) is a correct and self-documenting comparator. It also guards against overflow-style surprises with very large differences, since the caller never sees the raw magnitude.

Example · javascript
const nums = [10, -3, 7, 0, -8, 2];
console.log([...nums].sort((a, b) => Math.sign(a - b)));

// Sorting objects by a numeric field
const rows = [
  { name: "b", score: 5 },
  { name: "a", score: 12 },
  { name: "c", score: -1 },
];
rows.sort((x, y) => Math.sign(y.score - x.score));
console.log(rows.map((r) => r.name)); // ["a", "b", "c"]

Preserving sign while changing magnitude

Splitting sign from magnitude lets you clamp or round the size of a value without flipping its direction. The last block shows the trap: Math.sign(undefined) is NaN, and since NaN fails every comparison the code reports "flat" for what was actually invalid input.

Example · javascript
const capMagnitude = (x, cap) => Math.sign(x) * Math.min(Math.abs(x), cap);
console.log([15, -15, 4, -4].map((n) => capMagnitude(n, 10)));

// Away-from-zero rounding, unlike Math.round
const halfUp = (x) => Math.sign(x) * Math.round(Math.abs(x));
console.log(Math.round(-2.5), halfUp(-2.5)); // -2 -3

// NaN falls through a naive branch
const s = Math.sign(undefined);
console.log(s > 0 ? "up" : s < 0 ? "down" : "flat"); // "flat"

Discussion

  • Be the first to comment on this lesson.