Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does ~~ ("double tilde") do in Javascript?

Tags:

javascript

People also ask

What does double tilde mean JavaScript?

The “double tilde” (~~) operator is a double NOT Bitwise operator. Use it as a substitute for Math. floor(), since it's faster.

What does a double tilde mean?

Another approximation symbol is the double tilde ≈, meaning "approximately equal to". The tilde is also used to indicate congruence of shapes by placing it over an = symbol, thus ≅.

What does tilde do in JavaScript?

The (~) tilde operator takes any number and inverts the binary digits, for example, if the number is (100111) after inversion it would be (011000).

What does double tilde mean in R?

Tilde is a R's "Primitive Function" that does not evaluate its argument, and it is normally used to create a formula object as an inner-DSL role. I hijack this functionality to make an anounymous function. Double-tilde with a two-dots symbol, .. , makes an anonymous function in which two-dots plays a placeholder.


It removes everything after the decimal point because the bitwise operators implicitly convert their operands to signed 32-bit integers. This works whether the operands are (floating-point) numbers or strings, and the result is a number.

In other words, it yields:

function(x) {
  if(x < 0) return Math.ceil(x);
  else return Math.floor(x);
}

only if x is between -(231) and 231 - 1. Otherwise, overflow will occur and the number will "wrap around".

This may be considered useful to convert a function's string argument to a number, but both because of the possibility of overflow and that it is incorrect for use with non-integers, I would not use it that way except for "code golf" (i.e. pointlessly trimming bytes off the source code of your program at the expense of readability and robustness). I would use +x or Number(x) instead.


How this is the NOT of the NOT

The number -43.2, for example is:

-43.210 = 111111111111111111111111110101012

as a signed (two's complement) 32-bit binary number. (JavaScript ignores what is after the decimal point.) Inverting the bits gives:

NOT -4310 = 000000000000000000000000001010102 = 4210

Inverting again gives:

NOT 4210 = 111111111111111111111111110101012 = -4310

This differs from Math.floor(-43.2) in that negative numbers are rounded toward zero, not away from it. (The floor function, which would equal -44, always rounds down to the next lower integer, regardless of whether the number is positive or negative.)


The first ~ operator forces the operand to an integer (possibly after coercing the value to a string or a boolean), then inverts the lowest 31 bits. Officially ECMAScript numbers are all floating-point, but some numbers are implemented as 31-bit integers in the SpiderMonkey engine.

You can use it to turn a 1-element array into an integer. Floating-points are converted according to the C rule, ie. truncation of the fractional part.

The second ~ operator then inverts the bits back, so you know that you will have an integer. This is not the same as coercing a value to boolean in a condition statement, because an empty object {} evaluates to true, whereas ~~{} evaluates to false.

js>~~"yes"
0
js>~~3
3
js>~~"yes"
0
js>~~false
0
js>~~""
0
js>~~true
1
js>~~"3"
3
js>~~{}
0
js>~~{a:2}
0
js>~~[2]
2
js>~~[2,3]
0
js>~~{toString: function() {return 4}}
4
js>~~NaN
0
js>~~[4.5]
4
js>~~5.6
5
js>~~-5.6
-5

In ECMAScript 6, the equivalent of ~~ is Math.trunc:

Returns the integral part of a number by removing any fractional digits. It does not round any numbers.

Math.trunc(13.37)   // 13
Math.trunc(42.84)   // 42
Math.trunc(0.123)   //  0
Math.trunc(-0.123)  // -0
Math.trunc("-1.123")// -1
Math.trunc(NaN)     // NaN
Math.trunc("foo")   // NaN
Math.trunc()        // NaN

The polyfill:

function trunc(x) {
    return x < 0 ? Math.ceil(x) : Math.floor(x);
}

The ~ seems to do -(N+1). So ~2 == -(2 + 1) == -3 If you do it again on -3 it turns it back: ~-3 == -(-3 + 1) == 2 It probably just converts a string to a number in a round-about way.

See this thread: http://www.sitepoint.com/forums/showthread.php?t=663275

Also, more detailed info is available here: http://dreaminginjavascript.wordpress.com/2008/07/04/28/


Given ~N is -(N+1), ~~N is then -(-(N+1) + 1). Which, evidently, leads to a neat trick.


Just a bit of a warning. The other answers here got me into some trouble.

The intent is to remove anything after the decimal point of a floating point number, but it has some corner cases that make it a bug hazard. I'd recommend avoiding ~~.

First, ~~ doesn't work on very large numbers.

~~1000000000000 == -727279968

As an alternative, use Math.trunc() (as Gajus mentioned, Math.trunc() returns the integer part of a floating point number but is only available in ECMAScript 6 compliant JavaScript). You can always make your own Math.trunc() for non-ECMAScript-6 environments by doing this:

if(!Math.trunc){
    Math.trunc = function(value){
        return Math.sign(value) * Math.floor(Math.abs(value));
    }
}

I wrote a blog post on this for reference: http://bitlords.blogspot.com/2016/08/the-double-tilde-x-technique-in.html


Here is an example of how this operator can be used efficiently, where it makes sense to use it:

leftOffset = -(~~$('html').css('padding-left').replace('px', '') + ~~$('body').css('margin-left').replace('px', '')),

Source:

See section Interacting with points