Differentiating +0 and -0

Differentiating +0 and -0

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.

Differences between 0, -0 and +0

"Branch Cuts for Complex Elementary Functions or Much Ado About Nothing's Sign Bit " addresses the reasons for signed zeros. That kind of analysis informed IEEE-754 which is the basis for most modern instruction sets
and programming languages' floating point number behavior.

In brief, many common numeric functions can be continuous with signed zeroes at places where they cannot be with an unsigned zero leading to fewer NaN values and fewer special cases. Division is one such function.



Then, the question is: why is -0 treated separately than 0 and +0?

Just to be clear, there are only two zero values. -0 and +0. The tokens (0) can be substituted for the tokens (+0) wherever they occur without changing semantics.



The interesting fact is that 0 is equal with -0

0 === -0
true

This behavior is mandated by IEEE-754.

To test whether two numeric values are the "same":

function same(x, y) {
if (x === y) {
if (x !== 0) {
return true; // Non-zero values.
} else {
return (1/x === 1/y); // Test signed-ness of zeroes.
}
} else {
return x !== x && y !== y; // Treat NaNs the same
}
}

Is it possible to differentiate between 0 and -0?

It depends on the machine you're targeting.

On a machine that uses a 2's complement representation for integers there's no difference at bit-level between 0 and -0 (they have the same representation)

If your machine used one's complement, you definitely could

0000 0000   -> signed   0 
1111 1111 -> signed −0

Obviously we're talking about using native support, x86 series processors have native support for the two's complement representation of signed numbers. Using other representations is definitely possible but would probably be less efficient and require more instructions.

(As JerryCoffin also noted: even if one's complement has been considered mostly for historical reasons, signed magnitude representations are still fairly common and do have a separate representation for negative and positive zero)

Are +0 and -0 the same?

JavaScript uses IEEE 754 standard to represent numbers. From Wikipedia:

Signed zero is zero with an associated sign. In ordinary arithmetic, −0 = +0 = 0. However, in computing, some number representations allow for the existence of two zeros, often denoted by −0 (negative zero) and +0 (positive zero). This occurs in some signed number representations for integers, and in most floating point number representations. The number 0 is usually encoded as +0, but can be represented by either +0 or −0.

The IEEE 754 standard for floating point arithmetic (presently used by most computers and programming languages that support floating point numbers) requires both +0 and −0. The zeroes can be considered as a variant of the extended real number line such that 1/−0 = −∞ and 1/+0 = +∞, division by zero is only undefined for ±0/±0 and ±∞/±∞.

The article contains further information about the different representations.

So this is the reason why, technically, both zeros have to be distinguished.

However, +0 === -0 evaluates to true. Why is that (...) ?

This behaviour is explicitly defined in section 11.9.6, the Strict Equality Comparison Algorithm (emphasis partly mine):

The comparison x === y, where x and y are values, produces true or false. Such a comparison is performed as follows:

(...)

  • If Type(x) is Number, then

    1. If x is NaN, return false.
    2. If y is NaN, return false.
    3. If x is the same Number value as y, return true.
    4. If x is +0 and y is −0, return true.
    5. If x is −0 and y is +0, return true.
    6. Return false.

(...)

(The same holds for +0 == -0 btw.)

It seems logically to treat +0 and -0 as equal. Otherwise we would have to take this into account in our code and I, personally, don't want to do that ;)


Note:

ES2015 introduces a new comparison method, Object.is. Object.is explicitly distinguishes between -0 and +0:

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

JavaScript - Detecting the difference between positive zero and negative zero

1/val > 0 will do what you want. Returns true for positive and false for negative.

This works because 1/-0 returns negative infinity, and 1/0 returns positive infinity, which are then comparable. You could also do something like 1/val == Infinity.

How to distinguish -0 and 0 in JavaScript

You can also use Object.is:

const num1 = 0;const num2 = -0;console.log(Object.is(num1, num2));console.log(Object.is(num1, num1));

How to get a -0 result in floating point calculations and distinguish it from +0 in C#?

Here is a practical example of differentiating between the two without examining the bits. MSDN links here and here assisted me in constructing this example.

static void Main(string[] args)
{
float a = 5 / float.NegativeInfinity;
float b = 5 / float.PositiveInfinity;
float c = 1 / a;
float d = 1 / b;
Console.WriteLine(a);
Console.WriteLine(b);
Console.WriteLine(c);
Console.WriteLine(d);
}

Output:

0
0
-Infinity
Infinity

Take note that -0 and 0 both look the same for comparisons, output, etc. But if you divide 1 by them, you get a -Infinity or Infinity, depending on which zero you have.

Is there any way to compare negative 0 ie. -0 which is returned from Math.sign(-0)?

The above code is working even if I get "-0" negative 0 as result of
getDaysDiff().

Because 0 and -0 evaluate to 0.

Math.sign(-0) == Math.sign(0) //outputs true

0 == -0; //outputs true

0 === -0 //outputs true

String(-0) //outputs "0"

Edit:

I would suggest to simplify/modify the function so that it returns a boolean

otApp.TaskPanelUtils.getDaysDiff = function(task)
{
var current = new Date();
var taskDueDate = new Date(task.unformattedDueDate())
return ((current.getTime()-taskDueDate.getTime())/otApp.TaskPanelUtils.oneDay) > 0;
}

And use it as

if(otApp.TaskPanelUtils.getDaysDiff(taskItem))
{
tempItems.push(taskItem);
}


Related Topics



Leave a reply



Submit