Alex Rivera | Logout

How does !!~ (not not tilde/bang bang tilde) alter the result of a 'contains/included' Array method call?

Asked 2012-02-16T18:08:09.160
101

If you read the comments at the jQuery inArray page here, there's an interesting declaration:

!!~jQuery.inArray(elm, arr) 

Now, I believe a double-exclamation point will convert the result to type boolean, with the value of true. What I don't understand is what is the use of the tilde (~) operator in all of this?

var arr = ["one", "two", "three"];
if (jQuery.inArray("one", arr) > -1) { alert("Found"); }

Refactoring the if statement:

if (!!~jQuery.inArray("one", arr)) { alert("Found"); }

Breakdown:

jQuery.inArray("one", arr)     // 0
~jQuery.inArray("one", arr)    // -1 (why?)
!~jQuery.inArray("one", arr)   // false
!!~jQuery.inArray("one", arr)  // true

I also noticed that if I put the tilde in front, the result is -2.

~!!~jQuery.inArray("one", arr) // -2

I don't understand the purpose of the tilde here. Can someone please explain it or point me towards a resource?

Edit
Report

1 Answer

106

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


It works because JavaScript bitwise operations convert the operands to 32-bit signed integers in two's complement format. Thus !!~-1 is evaluated 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 at least one bit set to zero; inverting it will create a truthy value; applying ! operator twice to a truthy value returns boolean true.

When used with .indexOf() and we only 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 to false so this abomination cannot be reliably used to test for -1.

answered 2012-05-14T11:23:16.523

Your Answer