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!

Discussion (12)

rohansawant profile image
Rohan Sawant

Damn! I had not idea this was a thing!

Thanks for the great read! 🔥

asadm profile image
Asad Memon Author


savagepixie profile image

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)

asadm profile image
Asad Memon Author

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!

savagepixie profile image

Cheers! That is a considerable increase from parseInt indeed!

barzi profile image

Amazing article! Thank you

stevematdavies profile image
Stephen Matthew Davies

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

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
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.

asadm profile image
Asad Memon Author • Edited on

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.

iam10k profile image
Tyler Encke • Edited on

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

Firefox Results

lucashogie profile image
Lucas H.

Super interesting! Thank you for the read!