optimization - Why is Javascript's Math.floor the slowest way to calculate floor in Javascript? - Stack Overflow
Why not always use Math.round instead of Math.floor?
Well, they are two different functions, with two different uses. Math.floor() always rounds down to the nearest integer, while Math.round() will round up or down depending on what side of .5 the number falls on. So, the basic answer is that you use which one gets the result you expect.
When it comes to generating random numbers though, Math.floor() has a more even distribution than Math.round(). If you want to generate a random number between 0 and 2, take the following examples:
Math.floor(Math.random() * 3). Here, 0-0.999999 will give you 0, 1.0 to 1.999999 will give you 1, and 2.0 to 2.999999 will give you 2. Every number has a 33% chance of being the result.
Math.round(Math.random() * 2). Here, 0-0.499999 will give you 0, 0.5 to 1.499999 will give you 1, and 1.5 to 1.999999 will give you 2. Note that the range of numbers that lead to a 1 is twice as big as those that lead to 0 or 1. That is 25% chance of 0, 50% chance of 1, and 25% chance of 2.
Math.floor vs Math.round vs parseInt vs Bitwise jsPerf
Using Math.floor and modulus for pagination, will it always be correct?
Videos
The primary reason Math.floor is slower (where it actually is--in some tests I've done it's faster) is that it involves a function call. Older JavaScript implementations couldn't inline function calls. Newer engines can inline the call, or at least make the property lookup faster, but they still need a guard condition in case you (or some other script) overwrote the Math.floor function. The overhead is minimal though, so there's not much difference in speed.
More importantly though, as was mentioned in several comments, the other methods are not equivalent. They all work by doing bitwise operations. The bitwise operators automatically convert their operands to 32-bit integers by truncating the number. That's fine if the number fits in 32 bits, but JavaScript numbers are 64-bit floats, which could be much larger than 2147483647.
They also give a different result for negative numbers, since converting to integers truncates and Math.floor always rounds down. For example, Math.floor(-2.1) === -3, but (-2.1) | (-2.1) === -2.
If you know you are only dealing with positive numbers less than 2147483648, and you need to squeeze every bit of performance out of your code in older browsers (Make sure it's actually the bottleneck first. It probably isn't.), I would use an even simpler method: x|0. It doesn't evaluate the variable twice, and it works even if x is an expression (just be sure to put it in parentheses so you don't run into precedence issues).
It has nothing to do with modern browsers. It has to do with implementing the ECMA standard. You can't just change how a certain function performs even if there is a faster way. It could break existing code.
The Math.Floor has to account for a lot of different scenarios of handling different types. Could they have made different scenarios faster by taking short cuts as you described? Maybe they could, but that might have broken other scenarios. Just because something on the surface looks small, doesn't mean that there isn't an iceberg underneath.
When I read through the code of colleagues and public repos, I see Math.floor used like 20x more often than Math.round.
But why? Isn't Math.round more accurate than Math.floor? Shouldn't it be the other way around (using Math.round more often than Math.floor)?
Is Math.floor so much faster than Math.round or am I missing something?
Edit
I am aware that those two do different things. My point is that in my experience, Math.floor is much too often used, when Math.round would simply be more accurate.
Well, they are two different functions, with two different uses. Math.floor() always rounds down to the nearest integer, while Math.round() will round up or down depending on what side of .5 the number falls on. So, the basic answer is that you use which one gets the result you expect.
When it comes to generating random numbers though, Math.floor() has a more even distribution than Math.round(). If you want to generate a random number between 0 and 2, take the following examples:
Math.floor(Math.random() * 3). Here, 0-0.999999 will give you 0, 1.0 to 1.999999 will give you 1, and 2.0 to 2.999999 will give you 2. Every number has a 33% chance of being the result.
Math.round(Math.random() * 2). Here, 0-0.499999 will give you 0, 0.5 to 1.499999 will give you 1, and 1.5 to 1.999999 will give you 2. Note that the range of numbers that lead to a 1 is twice as big as those that lead to 0 or 1. That is 25% chance of 0, 50% chance of 1, and 25% chance of 2.
Math.floor - You have a rating system of stars, and you aren't breaking them up into half stars. You do a query to get all the votes and the math comes back to 4.7 stars. You would use Math.floor here so that you display 4 stars.
Math.ceil - You have a slider module that displays 3 slides at a time. This module contains 19 slides. 19/3 = 6.33. If you were to floor or round here you would end up with 6. But to make sure that all 19 slides are shown, you need 7 containers, so you use Math.ceil.
Math.round - Anytime you need the closest number without worrying about anything like the above scenarios.