Math.floor() in JavaScript is a static method of the Math object that rounds a number down to the nearest integer less than or equal to the given number.
It always rounds down, regardless of the fractional part.
Syntax:
Math.floor(x), wherexis the number to round.Returns the largest integer less than or equal to
x.
Examples:
Math.floor(5.95)→5Math.floor(5.05)→5Math.floor(-5.05)→-6(rounds toward negative infinity)Math.floor(4)→4(integers remain unchanged)
Key Points:
Always rounds down—unlike
Math.round()which rounds to the nearest integer.Works with positive and negative numbers.
Used commonly in pagination, array indexing, random number generation, and game development.
Not to be confused with
Math.trunc(), which simply removes the decimal part without rounding.
Practical Use Case:
// Generate a random integer between 1 and 10
const randomInt = Math.floor(Math.random() * 10) + 1;
console.log(randomInt); // Output: 1 to 10Note:
Math.floor()is well-supported across all modern browsers and environments.
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.
optimization - Why is Javascript's Math.floor the slowest way to calculate floor in Javascript? - Stack Overflow
javascript - What exactly does Math.floor do? - Stack Overflow
Why do we use Math.floor() for creating random numbers ...
Videos
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.
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.
No, in fact this line of code outputs 0:
Math.floor(0.9);
Math.floor always rounds to the nearest whole number that is smaller than your input. You might confuse it with Math.round, that rounds to nearest whole number.
This is why this code always outputs 1 or 0, since input never gets to 2 or bigger:
Math.floor(Math.random()*2)
There's actually three different rounding functions in JavaScript: Math.floor, its opposite Math.ceil and the "usual" Math.round.
These work like this:
Math.floor(0.1); // Outputs 0
Math.ceil(0.1); // Outputs 1
Math.round(0.1); // Outputs 0
Math.floor(0.9); // Outputs 0
Math.ceil(0.9); // Outputs 1
Math.round(0.9); // Outputs 1
Math.floor(0.5); // Outputs 0
Math.ceil(0.5); // Outputs 1
Math.round(0.5); // Outputs 1
The floor() method rounds a number DOWNWARDS to the nearest integer, and returns the result.
If the passed argument is an integer, the value will not be rounded.
Actually, there is much more alternative ways to remove the decimals from a number. But it's a tradeoff of readability and speed.
Choosing the right one depends on what you need. If you just need to just remove decimals, always use trunc() or bitwise operators.
The floor(), ceil() and round() are conceptually very different from trunc().
Math library
You already know these. Always use them in a standard, non-critical code.
var v = 3.14; [Math.trunc(v), Math.round(v), Math.floor(v), Math.ceil(v)]
// prints results
for different input values you get these results
v t r f c
3.87 : [ 3, 4, 3, 4]
3.14 : [ 3, 3, 3, 4]
-3.14 : [-3, -3, -4, -3]
-3.87 : [-3, -4, -4, -3]
Math.trunc() cuts away (truncates) the decimal places.
Math.round() rounds towards closest integer number.
Math.floor() rounds towards closest lower integer number. 3.5 -> 3 -3.5 -> -4
Math.ceil() rounds towards closest higher integer number. 3.5 -> 4 -3.5 -> -3
But this is more fun :)
Binary operations and bitwise operators
If you look at them in the code, it might not be apparent from the first glance what they do, so don't use them in normal code. Though in some cases, they might be useful. For example calculating coordinates in a <canvas/>. They are much faster, but come with limitations.
Conceptually, they work this way:
- The operands are converted to 32-bit signed integers and thus lose all decimal fractions.
ATTENTION:
Numbers with more than 32 bits get their most significant (leftmost) bits discarded and the leftmost bit becomes the new sign bit.[ 0b011100110111110100000000000000110000000000001, // 15872588537857 ~~0b011100110111110100000000000000110000000000001, // -1610588159 ~~0b10100000000000000110000000000001, // -1610588159 ]
Bitwise logical operators
- Each bit in the first operand is paired with the corresponding bit in the second operand. (First bit to first bit, second bit to second bit, and so on.)
- The operator is applied to each pair of bits, and the result is constructed bitwise.
Bitwise shift operators
- These operators take a
valueto be shifted and anumberof bit positions to shift thevalueby.
truncating
However, when truncating, we always use a 0, zero, a false as a second operand, that doesn't do anything to the original value, except for converting to integer, in these cases:
~ NOT ~~v
| OR v | 0
<< Left shift v << 0
>> Signed right shift v >> 0
>>> Zero-fill right shift v >>> 0
var v = 3.78;
[ ~~v , v | 0 , v << 0 , v >> 0 , v >>> 0 ]
// prints these results
3.78 : [ 3, 3, 3, 3, 3]
3.14 : [ 3, 3, 3, 3, 3]
-3.74 : [-3, -3, -3, -3, 4294967293]
-3.14 : [-3, -3, -3, -3, 4294967293]
Performance
https://jsperf.com/number-truncating-methods/1

The existing answers have explained well about the performance. However, I could not understand the functional difference between Math.trunc and Math.floor from either the question or the answers and hence I have put my finding in this answer.
Math.trunc rounds down a number to an integer towards 0 while Math.floor rounds down a number to an integer towards -Infinity. As illustrated with the following number line, the direction will be the same for a positive number while for a negative number, the directions will be the opposite.
trunc: towards 0
floor: towards -Infinity
-3 -2 -1 0 1 2 3
-Infinity ... ------+----|--+------+------+------+------+--|----+------ .... Infinity
b a
Demo:
var a = 2.3, b = -2.3;
console.log("\t\t\t" + a + "\t\t" + b + "\r\n" + "Math.trunc: " + Math.trunc(a) + "\t\t" + Math.trunc(b) + "\r\n" + "Math.floor: " + Math.floor(a) + "\t\t" + Math.floor(b));
Output:
2.3 -2.3
Math.trunc: 2 -2
Math.floor: 2 -3
Summary: Because with Math.round() the values in min and max are underrepresented.
let's have an example and compare the results when using Math.floor() and Math.random() respectively.
Just for clarity I've added the two formulas we're comparing:
min = 0;
max = 3;
result = Math.round(Math.random() * (max - min)) + min;
result = Math.floor(Math.random() * (max - min + 1)) + min;
| result | Math.round() | Math.floor() |
|:------:|:------------:|:------------:|
| 0 | 0.0 - 0.499 | 0 - 0.999 |
| 1 | 0.5 - 1.499 | 1 - 1.999 |
| 2 | 1.5 - 2.499 | 2 - 2.999 |
| 3 | 2.5 - 2.999 | 3 - 3.999 |
you see that 0 and 3 have only half as big of a range that produces them with Math.random() than every other range in out example.
Added a snippet to show that effect:
// the same random numbers for all arrays, nonone should say these would have any influence.
const randomNumbers = Array(10000).fill().map(Math.random);
//min <= random <= max
const min = 4, max = 7;
// the +1 is to do `random <= max` otherwise it would produce `random < max`
const floored = randomNumbers.map(random => Math.floor(random * (max - min + 1) + min));
const rounded = randomNumbers.map(random => Math.round(random * (max - min) + min));
//utility to count the number of occurances per value
const count = (acc, nr) => (acc[nr] = (acc[nr] || 0) + 1, acc);
console.log({
"Math.floor()": floored.reduce(count, {}),
"Math.round()": rounded.reduce(count, {})
});
.as-console-wrapper{top:0;max-height:100%!important}
This is the real reason, at least the way I see it, Math.random returns a float number between 0 (Included) and 1 (Not included), something like 0 - 0.9999999999999999 (I assume). Looking at this information we can easily think, ok, this is a percentage, so all We have to do is something like:
let max = 10;
console.log(Math.round(Math.random() * max))
Right?, Well, let's take a look at what our Math.random number should really represent in our range.
Let's say our range is min=1 and max=5, that creates five different possibilities: 1,2,3,4,5. If 0.9999999999999999, or 1 for simplicity, is the maximum number you can get from Math.random, we can divide it into the number of possibilities our range has, something like 1 / max, getting roughly 0.2 as the result, this means each possibility will be at least equal to this number multiplied by it's value, that said Math.random values in the following ranges would satisfy each possibility:
| From | To | Expected Result |
|---|---|---|
| 0 | 0.2 | 1 |
| 0.21 | 0.4 | 2 |
| 0.41 | 0.6 | 3 |
| 0.61 | 0.8 | 4 |
| 0.81 | 0.9999999999999999 | 5 |
Now let's look at what Math.round does:
console.log(0.25 * 5, 'rounded to:', Math.round(0.25 * 5));
//Prints 1.25 'rounded to:' 1
console.log(0.31 * 5, 'rounded to:', Math.round(0.31 * 5));
//Prints 1.55 'rounded to:' 2
console.log(0.85 * 5, 'rounded to:', Math.round(0.85 * 5));
//Prints 4.25 'rounded to:' 4
As you can see, in some situations (The floats for your min and the floats for you max) Math.round won't return the result we might be expecting, like in the first example, we were expecting 2 because 0.25 is greater than 0.2 and in the last example we were expecting 5 because 0.85 is greater than 0.8. This means that every float from 0.21 to 0.299999999999999 and from 0.81 to 0.899999999999999 will result in unexpected results, and this is why a Math.floor solution is preferred.
How about we divide our randomly generated float by our fixed possibility float?
console.log(0.25 / (1 / 5));//Prints 1.25
console.log(0.31 / (1 / 5));//Prints 1.5499999999999998
console.log(0.85 / (1 / 5));//Prints 4.25
If you look at these results, they can be fixed by rounding them down and making sure we at least get the min value by adding the min value at the end:
let min = 1;
let max = 5;
let r = Math.random();
let f = 1 / max;
let x = Math.floor(r / f) + min;
console.log(r, x);
Now We have another problem, if We change our min value to any number other than 1, we need to adjust our formula to cover the offset created in the number of possibilities. So if our range changed to min=2 and max=5 We now have four possibilities: 2,3,4,5 and our formula now includes (max - min + 1) to calculate de number of possibilities; The + 1 makes the range inclusive creating the slot needed for the four possibilities:
let min = 2;
let max = 5;
let r = Math.random();
let f = 1 / (max - min + 1);
let x = Math.floor(r / f) + min;
console.log(r, x);
Our final function would look like this:
const randomNumber = (min, max) => {
return Math.floor(Math.random() / (1 / (max - min + 1))) + min;
}
console.log(randomNumber(2, 5));
//If Math.random ever returns 0.999999999999999
console.log(Math.floor(0.999999999999999 / (1 / (5 - 2 + 1))) + 2);//Prints 5
console.log(Math.floor(0.249999999999999 / (1 / (5 - 2 + 1))) + 2);//Print 2
//Hope this never happens
console.log(Math.floor(0.25 / (1 / (5 - 2 + 1))) + 2);//Print 3
Which is the same as:
const randomNumber = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(randomNumber(2, 5));
//If Math.random ever returns 0.999999999999999
console.log(Math.floor(0.999999999999999 * (5 - 2 + 1)) + 2);//Prints 5
console.log(Math.floor(0.249999999999999 * (5 - 2 + 1)) + 2);//Print 2
//Hope this never happens
console.log(Math.floor(0.25 * (5 - 2 + 1)) + 2);//Print 3