It turns out +0 === -0
evaluates to true
despite +0 and −0 being different entities. So, how do you differentiate +0 from −0?
There is a hack:
if (1 / myZero > 0) {
// myZero is +0
} else {
// myZero is -0
}
Can I do better?
It turns out +0 === -0
evaluates to true
despite +0 and −0 being different entities. So, how do you differentiate +0 from −0?
There is a hack:
if (1 / myZero > 0) {
// myZero is +0
} else {
// myZero is -0
}
Can I do better?
In ECMAScript 6 Object.is
behaves like ===
except that it distinguishes positive and negative zeroes, and Object.is(NaN, NaN)
evaluates to true
. (See here for a writeup.)
Chrome 24 supports Object.is
.
This is still some kind of hack, but a look at the specs suggests this:
Math.atan2(0, -0) === Math.PI // true
Math.atan2(0, 0) === 0 // true
According to David Flanagan's book, p. 34, dividing 1 by your zero will produce the corresponding infinity, which can then be used in an equality check:
1 / 0
> Infinity
1 / -0
> -Infinity
And here's the behavior of the equality comparisons of infinities:
Infinity === -Infinity
> false
Infinity === Infinity
> true
-Infinity === Infinity
> false
-Infinity === -Infinity
> true
To check the negative zero, here is one simple solution.
function isNegativeZero(n) {
n = Number( n );
return (n === 0) && (1 / n === -Infinity);
}
As people seem stumped as to what the practical need for this would be: here is my use case...
I needed a solution to sort the columns of a table by their index. Click the <th>
and invoke the sorter with [ordinal] for ascending and -[ordinal] for descending. The first column would give -0
for descending or 0
for ascending.
So I need to differentiate between +0
and -0
and ended up here. The solution that worked for me is in the comment by @Šime Vidas, but is hidden away somewhat.
// This comparison works for all negatives including -0
if ( 1 / x > 0 ) { }
1 / -0 > 0 // false
1 / 0 > 0 // true
1 / -99 > 0 // false
1 / 99 > 0 // true
// WRONG: this naive comparison might give unexpected results
if ( x > 0 ) { }
-0 > 0 // true
// Gotcha
This returns +0:
-0 + 0
This doesn't help to differenciate -0 and +0, but this helps in ensuring that some value is not -0.
1 / -0 => -Infinity
1 / (-0 + 0) => Infinity
One straight option in Node.js is to use Buffer.
var negZero = Buffer('8000000000000000', 'hex')
var buf = Buffer(8);
buf.writeDoubleBE(myZero);
if (buf.equals(negZero)) {
// myZero is -0
} else {
// myZero is +0
}
Also, you can easily browserify them by buffer module.
As hinted at by Matt Fenwick, you could just do (using the var zero
):
if(1/zero===Infinity) {
// zero is +0
} else {
// zero is -0
}
Use Math.sign()
console.log(Math.sign( 1 / +0 ));
console.log(Math.sign( 1 / -0 ));