4

Can anybody explain:

  • why double bitwise NOT for Infinity returns 0?

    ~~Infinity //return 0
    
  • what happens under the hood?

  • what is the binary representation of Infinity in javascript?

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
luke
  • 3,531
  • 1
  • 26
  • 46
  • 5
    Not sure why the double is relevant. `~Infinity` is `-1`. – Evan Trimboli Jun 29 '17 at 13:24
  • 4
    "What is the binary representation of Infinity in javascript?" JS uses the IEEE 754 standard for floating point numbers, so it would be (for pos inifinity) 0 sign, all 1s for an exponent and the mantissa would be 0 (js numbers are 64b, but a 32b ieee754 inf would look like 0 1111 1111 0000 0000 0000 0000 0000 000) – Patrick Barr Jun 29 '17 at 13:28
  • 1
    You'll find some information here -> [Double bitwise NOT (~~)](https://j11y.io/cool-stuff/double-bitwise-not) – Roshana Pitigala Jun 29 '17 at 13:32
  • 1
    Update on my previous comment, according to [ES5 Section 4.3.22](http://www.ecma-international.org/ecma-262/5.1/#sec-4.3.22) Infinity isn't explicitly stated that it uses the IEEE754 standard (like NaN does), but according to [11.4.8](http://www.ecma-international.org/ecma-262/5.1/#sec-11.4.8) `ToInt32` is used in `~` which is described in [9.5](http://www.ecma-international.org/ecma-262/5.1/#sec-9.5) that NaN, +0, -0, +inf or -inf are converted to `+0` – Patrick Barr Jun 29 '17 at 13:47
  • Possible duplicate of [How ~(tilde)Infinity becomes -1](https://stackoverflow.com/questions/37882479/how-tildeinfinity-becomes-1) – Sinan Ünür Jun 29 '17 at 14:04

1 Answers1

5

Because you are not operating on the underlying bit pattern of a number in JavaScript.

You cannot do the equivalent of the following C code in JavaScript:

#include <inttypes.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>

int main(void) {
    double x = HUGE_VAL;
    uint64_t y = *((uint64_t *) &x);
    printf("%016" PRIx64 "\n", y);
    printf("%016" PRIx64 "\n", ~y);
    printf("%016" PRIx64 "\n", ~~y);
    return 0;
}

This prints:

7ff0000000000000
800fffffffffffff
7ff0000000000000

As MDN notes:

A bitwise operator treats their[sic] operands as a set of 32 bits (zeros and ones), rather than as decimal, hexadecimal, or octal numbers. ... Bitwise operators perform their operations on such binary representations, but they return standard JavaScript numerical values.

... values with the most significant (left-most) bit set to 1 represent negative numbers (two's-complement representation).

According to 11.4.8 in ES5, we have:

11.4.8 Bitwise NOT Operator ( ~ )

The production UnaryExpression : ~ UnaryExpression is evaluated as follows:

  • Let expr be the result of evaluating UnaryExpression.
  • Let oldValue be ToInt32(GetValue(expr)).
  • Return the result of applying bitwise complement to oldValue. The result is a signed 32-bit integer.

ToInt32(Infinity) is +0. The first ~ makes it 0xffffffff. The second ~ flips all bits to zero.

That is, it does the equivalent of the following C code:

#include <inttypes.h>
#include <math.h>
#include <stdio.h>

int main(void) {
    double x = HUGE_VAL;
    uint32_t y = x;
    printf("%08X\n", y);
    printf("%08X\n", ~y);
    printf("%08X\n", ~~y);
    return 0;
}

Output:

00000000
FFFFFFFF
00000000
Community
  • 1
  • 1
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339