Are +0 and -0 the same?

后端 未结 9 1946
花落未央
花落未央 2020-11-22 07:45

Reading through the ECMAScript 5.1 specification, +0 and -0 are distinguished.

Why then does +0 === -0 evaluate to true<

相关标签:
9条回答
  • 2020-11-22 08:01

    I just came across an example where +0 and -0 behave very differently indeed:

    Math.atan2(0, 0);  //returns 0
    Math.atan2(0, -0); //returns Pi
    

    Be careful: even when using Math.round on a negative number like -0.0001, it will actually be -0 and can screw up some subsequent calculations as shown above.

    Quick and dirty way to fix this is to do smth like:

    if (x==0) x=0;
    

    or just:

    x+=0;
    

    This converts the number to +0 in case it was -0.

    0 讨论(0)
  • 2020-11-22 08:04

    There are two possible values (bit representations) for 0. This is not unique. Especially in floating point numbers this can occur. That is because floating point numbers are actually stored as a kind of formula.

    Integers can be stored in separate ways too. You can have a numeric value with an additional sign-bit, so in a 16 bit space, you can store a 15 bit integer value and a sign-bit. In this representation, the value 1000 (hex) and 0000 both are 0, but one of them is +0 and the other is -0.

    This could be avoided by subtracting 1 from the integer value so it ranged from -1 to -2^16, but this would be inconvenient.

    A more common approach is to store integers in 'two complements', but apparently ECMAscript has chosen not to. In this method numbers range from 0000 to 7FFF positive. Negative numbers start at FFFF (-1) to 8000.

    Of course, the same rules apply to larger integers too, but I don't want my F to wear out. ;)

    0 讨论(0)
  • 2020-11-22 08:04

    We can use Object.is to distinguish +0 and -0, and one more thing, NaN==NaN.

    Object.is(+0,-0) //false
    
    Object.is(NaN,NaN) //true
    
    0 讨论(0)
  • 2020-11-22 08:04

    I'd blame it on the Strict Equality Comparison method ( '===' ). Look at section 4d

    see 7.2.13 Strict Equality Comparison on the specification

    0 讨论(0)
  • 2020-11-22 08:05

    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
    
    0 讨论(0)
  • 2020-11-22 08:13

    In the IEEE 754 standard used to represent the Number type in JavaScript, the sign is represented by a bit (a 1 indicates a negative number).

    As a result, there exists both a negative and a positive value for each representable number, including 0.

    This is why both -0 and +0 exist.

    0 讨论(0)
提交回复
热议问题