JavaScript Drop Decimal from Number
How to remove a decimal, with consideration to performance.
In the following examples, I’ll use Math.PI
for the number: 3.14159
Bitwise double not operator
This removes everything after the decimal, as bitwise operators convert operands to signed 32-bit integers. This works for numbers or strings, returning a number.
~~Math.PI
Bitwise or operator
Again here, bitwise operators convert operands to signed 32-bit integers.
Math.PI | 0
Signed right shift operator
And again, any numeric operand is converted to an integer.
Math.PI >> 0
parseInt
Parse the value as an integer — note that if the value is not a string, it’s first converted to one using the toString()
abstract operation.
parseInt(Math.PI)
Math.trunc
Math’s truncation methods cuts any digit right of the decimal.
Math.trunc(Math.PI)
Math.round
Unlike the methods above that truncate the number’s decimal, Math’s round argument is rounded to the next higher absolute value in the direction of positive infinity. As in, 0.5 rounds to 1, but note that -0.5 rounds to 0.
Math.round(Math.PI)
Math.floor
This function returns the largest integer less than or equal to the argument. For example, 0.9 returns 0, -0.1 returns -1.
Math.floor(Math.PI)
Math.ceil
Opposite of floor, math’s ceiling function returns the smallest integer greater than or equal to the argument. For example, 0.1 returns 1, -0.9 returns 0.
Math.ceil(Math.PI)
toFixed
This function converts a number into a string, keeping the number of digits specified, which by default is zero digits. While this drops decimals, note you end up with a string. For example here, the value is “3”.
Math.PI.toFixed()
Performance
Here’s a JSBenchmark test suite for comparing performance:
import * as JSBench from "jsbenchmark";
new JSBench.TestSuite({
async: true,
passes: 25,
operations: 1000000,
maxRuntime: 1000,
})
.add("double not operator", () => {
~~Math.PI;
})
.add("or operator", () => {
Math.PI | 0;
})
.add("signed right shift operator", () => {
Math.PI >> 0;
})
.add("parseInt", () => {
parseInt(Math.PI);
})
.add("round", () => {
Math.round(Math.PI);
})
.add("floor", () => {
Math.floor(Math.PI);
})
.add("ceil", () => {
Math.ceil(Math.PI);
})
.add("trunc", () => {
Math.trunc(Math.PI);
})
.add("toFixed", () => {
Math.PI.toFixed();
})
.on("test", (event) => {
const test = event.test;
const resultSet = event.resultSet;
console.log(test.name);
resultSet.log();
})
.on("suite", (event) => {
const result = event.result;
result.log();
})
.run();
Results:
It makes sense that toFixed()
comes in large due to string conversion, with inline bitwise operations slightly faster than Math
static methods.