Why JavaScript has two zeros: -0 and +0

A Tale of Two Zeroes

Since the early versions of JavaScript there have always been two ways of performing equality comparison:

  • Abstract Equality Comparison using == aka “double equals”
  • Strict Equality Comparison using === aka “triple equals”

ES6 delivered a third option in the form of the [Object.is](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) method. It has some slight differences that hint at problems you did not even know you had.

Perhaps a better question is, JavaScript has two zeroes? Why does JavaScript have two zeroes? Why would any language have two zeroes?

The name for this is Signed Zero. It turns out the reason that JavaScript has -0 is because it is a part of the IEEE 754 floating-point specification. Two zeroes are also present in other languages like Ruby as well.

The two zeroes in question are:

  • Positive zero +0
  • Negative zero -0

As one might expect, they are treated as “the same” by both equality comparisons methods above. After all, zero is zero.

-0 == +0   // true
-0 === +0  // true

That is where Object.is comes in. It treats the two zeroes as unequal.

Object.is(+0, -0)  // false

Pre-ES6 it is still possible to tell the two zeroes apart. Looking at the results from other operators offers a hint.

-0 > +0  // false
+0 > -0  // false
-0 + -0  // -0
-0 + +0  // +0
+0 + +0  // +0
+1 / -0  // -Infinity
+1 / +0  // +Infinity

The last two operations in particular are useful. Unlike say Ruby or Python where division by zero yields a ZeroDivisionError, JavaScript returns [Infinity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity). Now take a look at the polyfill for Object.is offered on MDN.

if (!Object.is) {
  Object.is = function(x, y) {
    // SameValue algorithm
    if (x === y) { // Steps 1-5, 7-10
      // Steps 6.b-6.e: +0 != -0
      return x !== 0 || 1 / x === 1 / y;
    } else {
      // Step 6.a: NaN == NaN
      return x !== x && y !== y;
    }
  };
}

Since division by signed zero in JavaScript returns signed infinity, those results can be compared to tell the two zeroes apart.

#JavaScript #WebDev

Why JavaScript has two zeros: -0 and +0
5.75 GEEK