Why I Stopped Using Bitwise to Round

on javascript

When I first started coding in Javascript one of my biggest worries was, is this the fastest way? I was concerned over every method call and minor optimization, it negatively impacted productivity and at the end of the day no one noticed the difference.

I eventually broke out of it and focused on getting code working, then if only necessary optimized. But one small optimization stayed with me, until it came crashing down.

In Javascript method calls are slow and doing a whole method call to simply round down a number feels like a waste of resources.

var number = Math.floor(10.3);

There must be a quicker way in terms of processing speed and typing. And there is, take a look at bitshift alternative to Math.round. We can use bitwise operators to round down or even do regular rounding and look at the simplicity of it.

// floor
var number = 10.3 | 0;
// round
var number = (10.3 + 0.5) | 0;

Take a look at the performence. I chose to use the pipe for rounding because it was shown to be the quickest. I used it for months until I realized it was the wrong tool for the job.

Bitwise operators have a couple problems, one of them is they round incorrectly on negative numbers.

var number = Math.floor(-2.3); // => -3
var number = -2.3 | 0; // => -2

You say, "but I won't use it on negative numbers promise". Ok fine, bitwise operators also don't handle NaN correctly.

var number = Math.floor(NaN); // => NaN
var number = NaN | 0; // => 0

Make sure you don't use it on NaN numbers and on large numbers as well. I encountered this problem and it was a pain to debug.

var number = Math.floor(14444323231.2); // => 14444323231
var number = 14444323231.2 | 0; // => 1559421343

Yes, large numbers don't work seamlessly with bitwise operators, so don't risk it. At this point I hope I convinced you to never use bitwise operators for rounding but just in case I left my best point for last. I'll use a quote from one of my favorite programming books -- C++ Coding Standards.

KISS (Keep It Simple Software): Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.

Your priority should be to make your code as simple, clear, correct and safe as possible. Those who are not familiar with pipe rounding will be reluctant to touch your code and if they do, they might break it. But everyone knows of bitwise rounding, you say. Well take a look at this.

var items = [1, 10, 3, 4];
var hasItem = ~items.indexOf(10);

This is a quicker way of writing items.indexOf(10) != -1. People are always coming up with cute ways of writing code but its intention isn't clear. Don't get cute with your code, it might bite you in the back later.

One last quote.

The first rule of optimization is: Don't do it. The second rule of optimization (For experts only) is: Don't do it yet. Measure twice, optimize once.