DEV Community

Asad Memon
Asad Memon

Posted on

The Mysterious Double Tilde (~~) Operation

Long ago, I was optimizing a hot-path in some game physics code which involved lots of Math.floor() and parseInt() operations. I came across a micro-optimization to cast float or string to int.

~~ operation

console.log(~~1.6); // 1

What's happening?

A single ~ is a unary operator that converts the given number N to -(N+1). For example:

console.log(~2);  // -3
console.log(~1);  // -2
console.log(~0);  // -1

This operation is a bit too specific to be useful to many. But when you apply this operation twice, it's equivalent to Math.floor or parseInt. Examples:

console.log(~~-1);    // -1
console.log(~~0);     // 0
console.log(~~1);     // 1
console.log(~~"-1");  // -1
console.log(~~"0");   // 0
console.log(~~2.4);  // 2
console.log(~~3.9);  // 3
console.log(~~"1");   // 1
console.log(~~true);  // 1
console.log(~~false); // 0

Should I use it in my code?

It depends. As I said, it's a micro-optimization and the performance gains are only significant if you are doing this operation a lot in your code. Do not use it if you care about readability of your code as it might confuse other developers in your team.

Performance comparison

I wrote a little perf-test script to compare.

On Desktop Chrome, Math.floor() is almost as fast as ~~:

On Desktop Safari, ~~ is way faster than both Math.floor() and parseInt():

On iPhone XS, ~~ is also way faster than the others:

Happy Coding!

Top comments (13)

Collapse
 
rohansawant profile image
Rohan Sawant

Damn! I had not idea this was a thing!

Thanks for the great read! 🔥

Collapse
 
asadm profile image
Asad Memon

Thanks!

Collapse
 
savagepixie profile image
SavagePixie

That's a very interesting little thing. Do you happen to have any concrete data (or general idea) as to how much it improves performance?

(I'm not trying to contest your point, I'm just curious)

Collapse
 
asadm profile image
Asad Memon

At the time I first found it, I do remember comparing perf and finding it faster.

I just wrote a quick perf test, see the updated article!

Collapse
 
savagepixie profile image
SavagePixie

Cheers! That is a considerable increase from parseInt indeed!

Collapse
 
havespacesuit profile image
Eric Sundquist

It is a good operator if you want a function that truncates toward zero.

Math.floor(-1.6) // -2
~~-1.6 // -1
Collapse
 
barzi profile image
Andy

Amazing article! Thank you

Collapse
 
stevematdavies profile image
Stephen Matthew Davies

I've been using double tilde ocassionally for a while, but I never knew about the single one!

Collapse
 
georgewl profile image
George WL

I think bitwise operations are always a bad idea.

If someone can't read it and guess what it does, then it shouldn't be used.

Collapse
 
asadm profile image
Asad Memon • Edited

You are right. It depends, as I said.

I used it because of perf gains I needed. Maybe a comment explaining the code line would be a good compromise for situations like this.

Collapse
 
lucashogie profile image
Lucas H.

Super interesting! Thank you for the read!

Collapse
 
iam10k profile image
Tyler Encke • Edited

On Firefox, Math.floor is actually faster by 23%.

Firefox Results

Collapse
 
orashus profile image
Rash Edmund Jr

woah,
i'm down for using this.
besides, it's obviously faster.

thank you for this.