Are +0 and -0 the same?

Reading through the ECMAScript 5.1 specification, +0 and -0 are distinguished.

Why then does +0 === -0 evaluate to true?

I'll add this as an answer because I overlooked @user113716's comment.

You can test for -0 by doing this:

function isMinusZero(value) {
  return 1/value === -Infinity;
}

isMinusZero(0); // false
isMinusZero(-0); // true

I just came across an example where +0 and -0 behave very differently indeed:

Math.atan2(0, 0);  //returns 0
Math.atan2(0, -0); //returns Pi

Be careful: even when using Math.round on a negative number like -0.0001, it will actually be -0 and can screw up some subsequent calculations as shown above.

Quick and dirty way to fix this is to do smth like:

if (x==0) x=0;

or just:

x+=0;

This converts the number to +0 in case it was -0.

In the IEEE 754 standard used to represent the Number type in JavaScript, the sign is represented by a bit (a 1 indicates a negative number).

As a result, there exists both a negative and a positive value for each representable number, including 0.

This is why both -0 and +0 exist.

Answering the original title Are +0 and -0 the same?:

brainslugs83 (in comments of answer by Spudley) pointed out an important case in which +0 and -0 in JS are not the same - implemented as function:

var sign = function(x) {
    return 1 / x === 1 / Math.abs(x);
}

This will, other than the standard Math.sign return the correct sign of +0 and -0.

Comments
  • possible duplicate of Differentiating +0 and -0
  • Note that in ES2015 you can use Object.is to distinguish +0 and -0
  • Quoting David Flanagan from JS the definitive guide: Underflow occurs when the result of a numeric operation is closer to zero than the smallest representable number. In this case, JavaScript returns 0. If underflow occurs from a negative number, JavaScript returns a special value known as "negative zero."
  • Related posts - Why is negative zero important? & Uses for negative zero floating point value?
  • Indeed 1/0 === Infinity; // true and 1/-0 === -Infinity; // true.
  • So we have 1 === 1 and +0 === -0 but 1/+0 !== 1/-0. How weird!
  • @Random: I think it's certainly better than +0 !== -0 ;) That could really create problems.
  • @FelixKling, or 0 !== +0 / 0 !== -0, which would indeed create problems too!
  • Actually, this behavior models limit calculation in math. For example function 1/x has a value infinity in 0, however, it is separated if we are approaching 0 from the positive of negative side; in the former, the result is +inf, in the latter, -inf.
  • Should probably check for == 0 as well, the above isMinusZero(-1e-323) returns true!
  • @Chris, limit of double precision exponent is e±308, your number can be represented only in denormalized form and different implementations have different opinions about where to support them at all or not. The point is, on some machines in some floating point modes your number is represented as -0 and on others as denormalized number 0.000000000000001e-308. Such floats, so fun