Skip to content

Instantly share code, notes, and snippets.

@VassilisPallas
Last active November 25, 2020 03:12
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save VassilisPallas/d73632e9de4794b7dd10b7408f7948e8 to your computer and use it in GitHub Desktop.
Save VassilisPallas/d73632e9de4794b7dd10b7408f7948e8 to your computer and use it in GitHub Desktop.
Equivalent to PHP function number_format in Javascript
const assert = require('assert');
const numberFormat = require('./numberFormat');
assert.strictEqual(
numberFormat(132323232320.321, 2, ',', '.'),
'132.323.232.320,32'
);
assert.strictEqual(
numberFormat(10.22),
'10.22'
);
assert.strictEqual(
numberFormat(100),
'100'
);
assert.strictEqual(
numberFormat(1000, 2, ',', '.'),
'1.000,00'
);
assert.strictEqual(
numberFormat(95**12, 2),
'540,360,087,662,636,990,201,856'
);
assert.strictEqual(
numberFormat(123e5, 2),
'12,300,000.00'
);
assert.strictEqual(
numberFormat(123e5),
'12,300,000'
);
assert.strictEqual(
numberFormat(123e-5),
'0.00'
);
assert.strictEqual(
numberFormat(123e-15),
'0'
);
assert.strictEqual(
numberFormat(123e-15, 15),
'0.000000000000123'
);
const splitThousands = (number) => (dec_point, thousands_point) => {
const splitNum = number.toString().split(dec_point);
splitNum[0] = splitNum[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousands_point);
return splitNum.join(dec_point);
};
const isBigNumber = (number) => number.toString().includes("e");
const isBigFloat = (number) => number.toString().includes("-");
const calcTrailing = (dec, len) => Number(dec) + 2 - len;
const handleBigFloats = (number, decimals) => {
if (!decimals) {
return "0";
}
const [numbers, dec] = number.toString().replace(".", "").split("e-");
const trailingZeros = calcTrailing(dec, numbers.length);
const res = `${"0.".padEnd(trailingZeros + 2, "0")}${numbers}`;
return decimals ? res.substring(0, 2) + res.substring(2, decimals + 2) : res;
};
const handleBigNumbers = (number, decimals, dec_point, thousands_point) => {
if (isBigFloat(number)) {
return handleBigFloats(number, decimals);
}
return splitThousands(BigInt(number))(dec_point, thousands_point);
};
function handleFiniteNumbers(number, decimals, dec_point, thousands_point) {
if (!isFinite(number)) {
throw new TypeError("number is not finite number");
}
if (!decimals) {
const len = number.toString().split(".").length;
decimals = len > 1 ? len : 0;
}
return splitThousands(
parseFloat(number).toFixed(decimals).replace(".", dec_point)
)(dec_point, thousands_point);
}
const numberFormat = (
number,
decimals,
dec_point = ".",
thousands_point = ","
) => {
if (number == null || typeof number !== "number") {
throw new TypeError("number is not valid");
}
if (isBigNumber(number)) {
return handleBigNumbers(number, decimals, dec_point, thousands_point);
}
return handleFiniteNumbers(number, decimals, dec_point, thousands_point);
};
module.exports = numberFormat;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment