Two "0"-0 and +0 in JavaScript

Source: Internet
Author: User
Tags pow throw exception

This document is translated from JavaScript ' s zeros

JavaScript has both zeros:? 0 and +0. This post explains, why, and where it matters in practice.
There are two "0" in JavaScript:-0 and +0. This article explains why, and points out the impact of actual production

1.The signed Zero
1. "-0"


Numbers always need to being encoded to being stored digitally. Why does some encodings have a zeros? As an example, let's look at encoding integers as 4-digit binary numbers, via the Sign-and-magnitude method. There, one uses one bit for the sign (0 if positive, 1 if negative) and the remaining bits for the magnitude (absolute Val UE). Therefore,? 2 and +2 are encoded as follows.
Binary 1010 is decimal? 2
Binary 0010 is decimal +2
Naturally, that's means that there would be is the zeros:1000 (? 0) and 0000 (+0).
In order to store numbers, it needs to be encoded as a two-tier system, but why would it encode two "0", for example, encode integers as 4-bit binary, because integers have positive negative, by symbolic numerical notation, with the first bit to represent the symbol (0 for positive numbers, 1 for negative numbers), and the remaining bits to represent the numeric value (absolute value).
So,-2 and +2 are encoded in the following form:
Binary 1010 Rep-2
Binary 0010 represents +2
Naturally, for "2" there will also be two: 1000 (-0) and 0000 (+0)

In JavaScript, all numbers is floating point numbers, encoded a double precision according to the IEEE 754 Floating point arithmetic. That standard handles the sign in a manner similar to sign-and-magnitude encoding for integers and therefore also have a SI Gned Zero. Whenever represent a number digitally, it can become so small that it's indistinguishable from 0, because the Encodin Precise enough to represent the difference. Then a signed zero allows your to record "from which direction" You approached zero, what sign the number is had before it was Considered zero. Wikipedia nicely sums up the pros and cons of signed zeros:
In JavaScript, all numbers are stored as floating-point numbers, encoded as double-precision floating-point number according to the IEEE 754 standard floating-point algorithm. This standard is similar to the notation of numeric notation to encode integers, so "0" will also appear. When you want to represent a number, he can represent a number that is less than the "0" difference, because the encoding method cannot accurately represent the difference. Use "0" to record a number before it is considered "0", is "from the direction of the Axis" to approach the real "0". Wikipedia made a good summary of the pros and cons of "0".

Reference It is claimed this inclusion of signed zero in IEEE 754 makes it much easier to achieve numerical accuracy in some C Ritical problems, in particular when computing with complex elementary functions. On the other hand, the concept of signed zero runs contrary to the general assumption made in most mathematical fields (an D in most mathematics courses) that negative zero is the same thing as zero. Representations that allow negative zero can is a source of errors in programs, as software developers does not realize (or May forget) that, while the other zero representations behave as equal under numeric comparisons, they is different bit pat Terns and yield different results in some operations.

The use of "-0" in the IEEE 754 standard makes it easier to solve key problems such as precision in complex mathematical calculations. On the other hand, the concept of "0" runs counter to the mathematical assumptions in most fields of mathematics (and mathematics), since "0" and "+0" are the same. Allow "-0" to exist, developers may not realize (or forget) this point, because two "0" binary representation of different, "0" existence, in some calculations will produce different results, resulting in the judgment of two numbers equivalent code may imply some errors.
There is no corresponding Chinese version of the English language, so I did the translation.


JavaScript goes to some lengths to hide the fact, there is, and zeros.
JavaScript does a lot of work to hide the fact that there are two "0".

2.Hiding The zero ' s sign
2. Hide the "0" symbol

In JavaScript, you'll usually write 0, which always means +0. But it also displays? 0 simply as 0. The following is the "what if"-if you have browser command line or the node. JS REPL:
It is generally assumed that the "0" shown in JavaScript means "+0". In fact, "0" is also shown directly as "0", the following example shows the execution in the browser command line and node. JS:

    1. >-0
    2. 0


The reason is and the standard toString () method converts both zeros to the same "0".
The reason is that the same result "0" is converted by calling the ToString () method according to rule two "0":

    1. > ( -0). ToString ()
    2. ' 0 '
    3. > (+0). ToString ()
    4. ' 0 '


The illusion of a single zero are also perpetrated by the equals operators. Even strict equality considers both zeros the same, making it very hard-tell them apart To).
equals the "= =" operator also treats "0" as such, even the congruent symbol "= = =" is judged equal to them, which makes it difficult for them to differentiate (but in some cases needs to be differentiated).

    1. > +0 = = = 0
    2. True


The same holds for the Less-than and Greater-than Operators–they consider both zeros equal.
A value greater than ">" Less than "<" also determines that two "0" are equal.

    1. >-0 < +0
    2. False
    3. > +0 <-0
    4. False



3.Where The zero ' s sign matters
3. The "0" symbol affects where

The sign of the 0 rarely influences results of computations. And +0 are the most common 0. Only a few operations produce 0, the most of the them just pass an existing? 0 through. This section shows a few examples where the sign matters. For each example, think about whether it could is used to tell? 0 and +0 apart, a task, we'll tackle in Sect. 4. In order to do the sign of a zero visible, we use the following function.
"-0" affects the computational results in some very rare places. Usually "+0" is the usual "0". Only a few operations produce the result of "0", most of them directly ignore the existence of "0". This section will show the circumstances under which "0" has an impact. Think of each of the following examples to distinguish between "0" and "+0", in the process of showing, in order to be able to clearly see "0", we will use the following function.

  1. function signed (x) {
  2. if (x = = 0) {
  3. //Isnegativezero () will be shown later "Isnegativezero () is given in the following article for"
  4. return Isnegativezero (x)?  " -0": "+0";
  5. } Else {
  6. ///Otherwise, fall back to the default "in other cases, use defaults"
  7. //We don ' t use x.tostring () so that x can is null or undefined "null or undefined cannot be used x.tostring () notation"
  8. return Number.prototype.toString.call (x);
  9. }
  10. }



3.1.Adding Zeros
3.1. Addition

Quoting Sect 11.6.3 of the ECMAScript 5.1 specification, "Applying the Additive Operators to Numbers":

Reference the sum of negative zeros is? 0. The sum of the positive zeros, or of the zeros of opposite sign, is +0.


For example:

Reference to ECMAScript 5.1 specification section 11.6.3, "deformation of addition"

Reference two "-0" to add "-0". Two "+0" added "+0", two "0" with the opposite symbol added "+0"


As follows:

    1. > Signed (-0 +-0)
    2. '-0 '
    3. > Signed (-0 + +0)
    4. ' +0 '


This doesn ' t give you a-to distinguish the zeros, because-what comes-is-as difficult to distinguish as-what go Es in.
This does not tell you how to differentiate two "0" because the input and output of the operation are as difficult to distinguish.

3.2.Multiplying by Zero
3.2. Multiplication

When multiplying with zero and a finite number, the usual sign rules apply:
When two non-infinite numbers are multiplied by "0", the usual multiplication rules can be used.

    1. > Signed (+0 *-5)
    2. '-0 '
    3. > Signed (-0 *-5)
    4. ' +0 '


Multiplying an infinity with a zero results in NaN:
The infinity number is multiplied by "0" and the result is not a number (NaN)

    1. >-infinity * +0
    2. NaN



3.3.Dividing by Zero
3.3. Division

You can divide any Non-zero number (including infinities) by zero. The result is a infinity whose sign was subject to the usual rules.
Use any non-zero (including infinity) to divide by "0". The result conforms to the usual symbolic rules.

    1. > 5/+0
    2. Infinity
    3. > 5/-0
    4. -infinity
    5. >-infinity/+0
    6. -infinity


Note that-infinity and +infinity can be distinguished via = = =.
Note that positive infinity and negative infinity can be distinguished by "= = =".

    1. >-infinity = = = Infinity
    2. False


Dividing a zero by a zero results in Nan: "0" divided by "0" for non-numeric (Nan).

    1. > 0/0
    2. NaN
    3. > +0/-0
    4. NaN



3.4.math.pow ()
3.4. The exponentiation operation

The following is a table of the results of Math.pow () if the first argument is zero:
The following table lists the results of the multiplication operation with "0" as the base

    1. Pow (+0, y<0) →+∞
    2. Pow (? 0, Odd y<0) →?∞ //"odd number of powers"
    3. Pow (? 0, even y<0) →+∞ //"Even number power"


Interaction:

    1. > Math.pow (+0,-1)
    2. Infinity
    3. > Math.pow (-0,-1)
    4. -infinity



3.5.math.atan2 ()
3.5. Polar coordinates radians

The following is a table of the results so is returned if one of the arguments is zero.
The following table lists the return values for the target point horizontal ordinate to zero

    1. Atan2 (+0, +0) →+0
    2. Atan2 (+0,? 0) →+π
    3. Atan2 (? 0, +0) →?0
    4. Atan2 (? 0,? 0) →?π
    5. Atan2 (+0, x<0) →+π
    6. Atan2 (? 0, X<0) →?π


Hence, there is several ways to determine the sign of a zero. For example:
Therefore, we found a method that distinguishes two zeros, such as:

    1. > math.atan2 (-0,-1)
    2. -3.141592653589793
    3. > math.atan2 (+0,-1)
    4. 3.141592653589793


Atan2 is one of the few operations this produces? 0 for Non-zero arguments:
Atan2 is one of the few operations that can produce "0" with a non-0 parameter

    1. Atan2 (y>0, +∞) →+0
    2. Atan2 (y<0, +∞) →?0


Therefore: So

    1. > Signed (math.atan2 ( -1, Infinity))
    2. '-0 '



3.6.math.round ()
3.6. Rounding

Math.Round () is another operation this returns? 0 for arguments other than? 0 and + 0:
Math.Round () is another operation that does not use "-0" and "0" to produce "0".

    1. > Signed (Math.Round (-0.1))
    2. '-0 '


Here we have the effect so we talked about at the beginning:the sign of the zero records the sign of the value before R Ounding, "from which side" we approached 0.
Now we can realize that the previous article "0" can record a number before it is considered "0", is "from the direction of the Axis" to approach the real "0". "Meaning of it.

4.Telling the Zeros Apart
4. Distinguish two "0"

The canonical solution for determining the sign of a, zero is to divide one by it and then check whether the result Is-inf Inity or +infinity:
A typical way to discern the "0" notation is to check that "1" is divided by whether the result of the operation is positive infinity or negative infinity:

    1. function Isnegativezero (x) {
    2. return x = = = 0 && (1/x < 0);
    3. }


The above sections showed several other options. One original solution comes from Allen wirfs-brock. Here is a slightly modified version of it:
The previous article also shows some other options. Allen Wirfs-brock also provides a method based on object prototyping, which has a slightly modified version.

  1. function Isnegativezero (x) {
  2. if (x!== 0) return false;
  3. var obj = {};
  4. Object.defineproperty (obj, ' z ', {value:-0, Configurable: false});
  5. try {
  6. //is x different from Z ' s previous value? Then throw exception. "If X is different from the z value defined earlier, an exception is thrown. "
  7. Object.defineproperty (obj, ' z ', {value:x});
  8. } catch (e) {
  9. return false
  10. };
  11. return true;
  12. }


Explanation:in General, you cannot redefine a non-configurable Property–an exception would be thrown. For example:
Description: Typically, you cannot redefine a "non-configurable" (non-configurable) property, if doing so throws the following exception:

    1. Typeerror:cannot Redefine Property:z


However, JavaScript would ignore your attempt if you use the same value as the existing one. In this case, whether a value was the same is not determined via = = =, but via an internal operation that distinguishes? 0 A nd +0. You can read up on the details in Wirfs-brock's blog post (freezing an object makes all properties non-configurable).
JavaScript tries to ignore the changes you made to the same value. In this example, the same value is not judged by the equality operator "= = =", which distinguishes between "0" and "+0" through an intrinsic mechanism. Details can be read Wirfs-brock's blog "Set all properties to be non-configurable to implement object locking (freezing an object makes all properties non-configurable)"

5.Conclusion
5. Conclusion

We have seen-there is-zeros, because of how the sign was encoded for JavaScript ' s numbers. However,? 0 is normally hidden and it's best to pretend that there are only one zero. Especially, because the difference between the zeros have little bearing on computations. Even strict equality = = = Can ' t tell them apart. Should you, against all expectations or just for fun, need to determine the sign of a zero, there is several ways to do s O. Note that the slightly quirky existence of the zeros are not JavaScript's fault, it simply follows the IEEE 754 standard For floating point numbers.
We have seen how the two zero symbols are encoded in JavaScript. Although usually "0" is hidden well, the camouflage achievement looks like only one "0" exists. In particular, some operations obscure this little difference. So that the strict "= = =" Operation can not distinguish them. If you want to differentiate between two "0", whether it's intentional or just for fun, here are a few ways to do it. Note that there are two "0" quirks, not JavaScript bugs, but compliance with the rules of the IEEE 754 specification for floating-point numbers.

6.Related Reading
6. Extended Reading

This post was part of a series on JavaScript numbers that comprises the following posts:

    • Integers and shift operators in JavaScript
    • Displaying numbers in JavaScript

Furthermore, the blog post "stricter equality in JavaScript" examines that = = = cannot detect either the value NaN or the S IGN of a zero.
This article is part of a series of articles that discuss numbers in JavaScript, and other articles in the series are below:

    • Integer and transform operations in JavaScript
    • Digital display operations in JavaScript

In addition, the rigorous comparison in JavaScript examines the various situations where "= = =" cannot be used to check NaN or "0".

Two "0"-0 and +0 in JavaScript

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.