[ACCEPTED]-How does !!~ (not not tilde/bang bang tilde) alter the result of a 'contains/included' Array method call?-bitwise-operators

Accepted answer
Score: 124

There's a specfic reason you'll sometimes 17 see ~ applied in front of $.inArray.

Basically,

~$.inArray("foo", bar)

is 16 a shorter way to do

$.inArray("foo", bar) !== -1

$.inArray returns the index of 15 the item in the array if the first argument 14 is found, and it returns -1 if its not found. This 13 means that if you're looking for a boolean 12 of "is this value in the array?", you can't 11 do a boolean comparison, since -1 is a truthy 10 value, and when $.inArray returns 0 (a falsy 9 value), it means its actually found in the 8 first element of the array.

Applying the 7 ~ bitwise operator causes -1 to become 0, and 6 causes 0 to become `-1. Thus, not finding 5 the value in the array and applying the 4 bitwise NOT results in a falsy value (0), and 3 all other values will return non-0 numbers, and 2 will represent a truthy result.

if (~$.inArray("foo", ["foo",2,3])) {
    // Will run
}

And it'll 1 work as intended.

Score: 106

!!~expr evaluates to false when expr is -1 otherwise true.
It 11 is same as expr != -1, only broken*


It works because 10 JavaScript bitwise operations convert the operands to 32-bit signed integers 9 in two's complement format. Thus !!~-1 is evaluated 8 as follows:

   -1 = 1111 1111 1111 1111 1111 1111 1111 1111b // two's complement representation of -1
  ~-1 = 0000 0000 0000 0000 0000 0000 0000 0000b // ~ is bitwise not (invert all bits)
   !0 = true                                     // ! is logical not (true for falsy)
!true = false                                    // duh

A value other than -1 will have 7 at least one bit set to zero; inverting 6 it will create a truthy value; applying 5 ! operator twice to a truthy value returns 4 boolean true.

When used with .indexOf() and we only 3 want to check if result is -1 or not:

!!~"abc".indexOf("d") // indexOf() returns -1, the expression evaluates to false
!!~"abc".indexOf("a") // indexOf() returns  0, the expression evaluates to true
!!~"abc".indexOf("b") // indexOf() returns  1, the expression evaluates to true

* !!~8589934591 evaluates 2 to false so this abomination cannot be reliably used 1 to test for -1.

Score: 57

The tilde operator isn't actually part of 8 jQuery at all - it's a bitwise NOT operator 7 in JavaScript itself.

See The Great Mystery of the Tilde(~).

You are getting 6 strange numbers in your experiments because 5 you are performing a bitwise logical operation 4 on an integer (which, for all I know, may 3 be stored as two's complement or something 2 like that...)

Two's complement explains how to represent 1 a number in binary. I think I was right.

Score: 35

~foo.indexOf(bar) is a common shorthand to represent foo.contains(bar) because 5 the contains function doesn't exist.

Typically the 4 cast to boolean is unnecessary due to JavaScript's 3 concept of "falsy" values. In this case 2 it's used to force the output of the function 1 to be true or false.

Score: 18

jQuery.inArray() returns -1 for "not found", whose complement 5 (~) is 0. Thus, ~jQuery.inArray() returns a falsy value (0) for 4 "not found", and a truthy value (a negative 3 integer) for "found". !! will then formalise 2 the falsy/truthy into real boolean false/true. So, !!~jQuery.inArray() will 1 give true for "found" and false for "not found".

Score: 13

The ~ for all 4 bytes int is equal to this formula 1 -(N+1)

SO

~0   = -(0+1)   // -1
~35  = -(35+1)  // -36 
~-35 = -(-35+1) //34 
Score: 11

Tilde is bitwise NOT - it inverts each bit 6 of the value. As a general rule of thumb, if 5 you use ~ on a number, its sign will be inverted, then 4 1 will be subtracted.

Thus, when you do ~0, you 3 get -1 (0 inverted is -0, subtract 1 is 2 -1).

It's essentially an elaborate, super-micro-optimised 1 way of getting a value that's always Boolean.

Score: 10

The ~ operator is the bitwise complement 11 operator. The integer result from inArray() is either 10 -1, when the element is not found, or some 9 non-negative integer. The bitwise complement 8 of -1 (represented in binary as all 1 bits) is 7 zero. The bitwise-complement of any non-negative 6 integer is always non-zero.

Thus, !!~i will be 5 true when integer "i" is a non-negative integer, and 4 false when "i" is exactly -1.

Note that ~ always 3 coerces its operand to integer; that is, it 2 forces non-integer floating point values 1 to integer, as well as non-numeric values.

Score: 8

You're right: This code will return false when 3 the indexOf call returns -1; otherwise true.

As you 2 say, it would be much more sensible to use 1 something like

return this.modifiedPaths.indexOf(path) !== -1;
Score: 6

The ~ operator is the bitwise NOT operator. What 5 this means is that it takes a number in 4 binary form and turns all zeroes into ones 3 and ones into zeroes.

For instance, the number 2 0 in binary is 0000000, while -1 is 11111111. Likewise, 1 1 is 00000001 in binary, while -2 is 11111110.

Score: 3

My guess is that it is there because it's 9 a few characters shorter (which library 8 authors are always after). It also uses 7 operations that only take a few machine 6 cycles when compiled into the native code 5 (as opposed to the comparison to a number.)

I 4 agree with another answer that it's an overkill 3 but perhaps might make sense in a tight 2 loop (requires performance gain estimation, though, otherwise 1 may turn out to be premature optimization.)

Score: 2

I assume, since it is a bitwise operation, it 2 is the fastest (computationally cheap) way 1 to check whether path appears in modifiedPaths.

Score: 1

As (~(-1)) === 0, so:

!!(~(-1)) === Boolean(~(-1)) === Boolean(0) === false

0

More Related questions