Дифференцируя +0 и -0

Оказывается, +0 === -0 оценивается как true, несмотря на то, что +0 и -0 являются разными объектами. Итак, как вы отличаете +0 от -0?

Есть взлома:

if (1 / myZero > 0) {
   // myZero is +0
} else {
   // myZero is -0
}

Могу ли я лучше?

Ответы

Ответ 1

В ECMAScript 6 Object.is ведет себя как ===, за исключением того, что он отличает положительные и отрицательные нули, а Object.is(NaN, NaN) оценивается как true. (См. здесь для записи.)

Chrome 24 поддерживает Object.is.

Ответ 2

Это еще какой-то хак, но посмотрите на спецификации:

Math.atan2(0, -0) === Math.PI // true
Math.atan2(0,  0) === 0       // true

Ответ 3

Согласно книга Дэвида Фланагана, стр. 34, деление 1 на нуль приведет к соответствующей бесконечности, которая затем может быть использована при проверке равенства:

1 / 0
> Infinity
1 / -0
> -Infinity

И здесь поведение сравнений равенств бесконечности:

Infinity === -Infinity
> false
Infinity === Infinity
> true
-Infinity === Infinity
> false
-Infinity === -Infinity
> true

Ответ 4

Это возвращает +0:

-0 + 0

Это не помогает различать -0 и +0, но это помогает в обеспечении того, что какое-то значение не равно -0.

1 / -0       => -Infinity  
1 / (-0 + 0) => Infinity

Ответ 5

Как люди кажутся тупыми в отношении того, что практическая необходимость в этом будет: вот мой прецедент...

Мне нужно решение для сортировки столбцов таблицы по их индексу. Нажмите <th> и вызовите сортировщика с порядковым номером для увеличения и - [порядковый номер] для нисходящего. Первый столбец дал бы -0 для нисходящего или 0 для восхождения.

Поэтому мне нужно провести различие между +0 и -0 и закончил здесь. Решение, которое работало для меня, находится в комментарии @Šime Vidas, но немного скроется.

// 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

Ответ 6

Чтобы проверить отрицательный ноль, вот одно простое решение.

function isNegativeZero(n) {
    n = Number( n );
    return (n === 0) && (1 / n === -Infinity);
}

Ответ 7

Один прямой вариант в Node.js - использовать Buffer.

var negZero = Buffer('8000000000000000', 'hex')

var buf = Buffer(8);
buf.writeDoubleBE(myZero);

if (buf.equals(negZero)) {
    // myZero is -0
} else {
    // myZero is +0
}

Кроме того, вы можете легко их обозревать с помощью буферного модуля.

Ответ 8

Как намекнул Мэтт Фенвик, вы могли бы просто сделать (используя var zero):

if(1/zero===Infinity) {
  // zero is +0
} else {
  // zero is -0
}