Hướng dẫn javascript round decimal

In general, decimal rounding is done by scaling: round(num * p) / p

Nội dung chính

  • How do I round to a specific decimal in JavaScript?
  • How do you round a number to 2 decimal places in JavaScript?
  • How do you control decimal places in JavaScript?

Naive implementation

Using the following function with halfway numbers, you will get either the upper rounded value as expected, or the lower rounded value sometimes depending on the input.

This inconsistency in rounding may introduce hard to detect bugs in the client code.

function naiveRound(num, decimalPlaces = 0) { var p = Math.pow(10, decimalPlaces); return Math.round(num * p) / p; } console.log( naiveRound(1.245, 2) ); // 1.25 correct (rounded as expected) console.log( naiveRound(1.255, 2) ); // 1.25 incorrect (should be 1.26) // testing edge cases console.log( naiveRound(1.005, 2) ); // 1 incorrect (should be 1.01) console.log( naiveRound(2.175, 2) ); // 2.17 incorrect (should be 2.18) console.log( naiveRound(5.015, 2) ); // 5.01 incorrect (should be 5.02)

In order to determine whether a rounding operation involves a midpoint value, the Round function multiplies the original value to be rounded by 10 ** n, where n is the desired number of fractional digits in the return value, and then determines whether the remaining fractional portion of the value is greater than or equal to .5. This "Exact Testing for Equality" with floating-point values are problematic because of the floating-point format's issues with binary representation and precision. This means that any fractional portion of a number that is slightly less than .5 (because of a loss of precision) will not be rounded upward.

In the previous example, 5.015 is a midpoint value if it is to be rounded to two decimal places, the value of 5.015 * 100 is actually 501.49999999999994. Because .49999999999994 is less than .5, it is rounded down to 501 and finally the result is 5.01.

Better implementations

Exponential notation

By converting the number to a string in the exponential notation, positive numbers are rounded as expected. But, be aware that negative numbers round differently than positive numbers.

In fact, it performs what is basically equivalent to "round half up" as the rule, you will see that round(-1.005, 2) evaluates to -1 even though round(1.005, 2) evaluates to 1.01. The lodash _.round method uses this technique.

/** * Round half up ('round half towards positive infinity') * Negative numbers round differently than positive numbers. */ function round(num, decimalPlaces = 0) { num = Math.round(num + "e" + decimalPlaces); return Number(num + "e" + -decimalPlaces); } // test rounding of half console.log( round(0.5) ); // 1 console.log( round(-0.5) ); // 0 // testing edge cases console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1 console.log( round(-2.175, 2) ); // -2.17 console.log( round(-5.015, 2) ); // -5.01

If you want the usual behavior when rounding negative numbers, you would need to convert negative numbers to positive before calling Math.round(), and then convert them back to negative numbers before returning.

// Round half away from zero function round(num, decimalPlaces = 0) { if (num < 0) return -round(-num, decimalPlaces); num = Math.round(num + "e" + decimalPlaces); return Number(num + "e" + -decimalPlaces); }

Approximate rounding

To correct the rounding problem shown in the previous naiveRound example, we can define a custom rounding function that performs a "nearly equal" test to determine whether a fractional value is sufficiently close to a midpoint value to be subject to midpoint rounding.

// round half away from zero function round(num, decimalPlaces = 0) { if (num < 0) return -round(-num, decimalPlaces); var p = Math.pow(10, decimalPlaces); var n = num * p; var f = n - Math.floor(n); var e = Number.EPSILON * n; // Determine whether this fraction is a midpoint value. return (f >= .5 - e) ? Math.ceil(n) / p : Math.floor(n) / p; } // test rounding of half console.log( round(0.5) ); // 1 console.log( round(-0.5) ); // -1 // testing edge cases console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log( round(-5.015, 2) ); // -5.02

Number.EPSILON

There is a different purely mathematical technique to perform round-to-nearest (using "round half away from zero"), in which epsilon correction is applied before calling the rounding function.

Simply, we add the smallest possible float value (= 1.0 ulp; unit in the last place) to the product before rounding. This moves to the next representable float value, away from zero, thus it will offset the binary round-off error that may occur during the multiplication by 10 ** n.

/** * Round half away from zero ('commercial' rounding) * Uses correction to offset floating-point inaccuracies. * Works symmetrically for positive and negative numbers. */ function round(num, decimalPlaces = 0) { var p = Math.pow(10, decimalPlaces); var n = (num * p) * (1 + Number.EPSILON); return Math.round(n) / p; } // rounding of half console.log( round(0.5) ); // 1 console.log( round(-0.5) ); // -1 // testing edge cases console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log( round(-5.015, 2) ); // -5.02

After adding 1 ulp, the value of 5.015 * 100 which is 501.49999999999994 will be corrected to 501.50000000000006, this will rounded up to 502 and finally the result is 5.02.

Note that the size of a unit in last place ("ulp") is determined by (1) the magnitude of the number and (2) the relative machine epsilon (2^-52). Ulps are relatively larger at numbers with bigger magnitudes than they are at numbers with smaller magnitudes.

Double rounding

Here, we use the toPrecision() method to strip the floating-point round-off errors in the intermediate calculations. Simply, we round to 15 significant figures to strip the round-off error at the 16th significant digit. This technique to preround the result to significant digits is also used by PHP 7 round function.

The value of 5.015 * 100 which is 501.49999999999994 will be rounded first to 15 significant digits as 501.500000000000, then it will rounded up again to 502 and finally the result is 5.02.

// Round half away from zero function round(num, decimalPlaces = 0) { if (num < 0) return -round(-num, decimalPlaces); var p = Math.pow(10, decimalPlaces); var n = (num * p).toPrecision(15); return Math.round(n) / p; } // rounding of half console.log( round(0.5) ); // 1 console.log( round(-0.5) ); // -1 // testing edge cases console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log( round(-5.015, 2) ); // -5.02

Arbitrary-precision JavaScript library - decimal.js

// Round half away from zero function round(num, decimalPlaces = 0) { return new Decimal(num).toDecimalPlaces(decimalPlaces).toNumber(); } // rounding of half console.log( round(0.5) ); // 1 console.log( round(-0.5) ); // -1 // testing edge cases console.log( round(1.005, 2) ); // 1.01 console.log( round(2.175, 2) ); // 2.18 console.log( round(5.015, 2) ); // 5.02 console.log( round(-1.005, 2) ); // -1.01 console.log( round(-2.175, 2) ); // -2.18 console.log( round(-5.015, 2) ); // -5.02<script src="//cdnjs.cloudflare.com/ajax/libs/decimal.js/10.2.1/decimal.js" integrity="sha512-GKse2KVGCCMVBn4riigHjXE8j5hCxYLPXDw8AvcjUtrt+a9TbZFtIKGdArXwYOlZvdmkhQLWQ46ZE3Q1RIa7uQ==" crossorigin="anonymous"></script>

Solution 1: string in exponential notation

Inspired by the solution provided by KFish here: //stackoverflow.com/a/55521592/4208440

A simple drop in solution that provides accurate decimal rounding, flooring, and ceiling to a specific number of decimal places without adding a whole library. It treats floats more like decimals by fixing the binary rounding issues to avoid unexpected results: for example, floor((0.1+0.7)*10) will return the expected result 8.

Numbers are rounded to a specific number of fractional digits. Specifying a negative precision will round to any number of places to the left of the decimal point.

// Solution 1 var DecimalPrecision = (function() { if (Math.trunc === undefined) { Math.trunc = function(v) { return v < 0 ? Math.ceil(v) : Math.floor(v); }; } var decimalAdjust = function myself(type, num, decimalPlaces) { if (type === 'round' && num < 0) return -myself(type, -num, decimalPlaces); var shift = function(value, exponent) { value = (value + 'e').split('e'); return +(value[0] + 'e' + (+value[1] + (exponent || 0))); }; var n = shift(num, +decimalPlaces); return shift(Math[type](n), -decimalPlaces); }; return { // Decimal round (half away from zero) round: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces); }, // Decimal ceil ceil: function(num, decimalPlaces) { return decimalAdjust('ceil', num, decimalPlaces); }, // Decimal floor floor: function(num, decimalPlaces) { return decimalAdjust('floor', num, decimalPlaces); }, // Decimal trunc trunc: function(num, decimalPlaces) { return decimalAdjust('trunc', num, decimalPlaces); }, // Format using fixed-point notation toFixed: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces).toFixed(decimalPlaces); } }; })(); // test rounding of half console.log(DecimalPrecision.round(0.5)); // 1 console.log(DecimalPrecision.round(-0.5)); // -1 // testing very small numbers console.log(DecimalPrecision.ceil(1e-8, 2) === 0.01); console.log(DecimalPrecision.floor(1e-8, 2) === 0); // testing simple cases console.log(DecimalPrecision.round(5.12, 1) === 5.1); console.log(DecimalPrecision.round(-5.12, 1) === -5.1); console.log(DecimalPrecision.ceil(5.12, 1) === 5.2); console.log(DecimalPrecision.ceil(-5.12, 1) === -5.1); console.log(DecimalPrecision.floor(5.12, 1) === 5.1); console.log(DecimalPrecision.floor(-5.12, 1) === -5.2); console.log(DecimalPrecision.trunc(5.12, 1) === 5.1); console.log(DecimalPrecision.trunc(-5.12, 1) === -5.1); // testing edge cases for round console.log(DecimalPrecision.round(1.005, 2) === 1.01); console.log(DecimalPrecision.round(39.425, 2) === 39.43); console.log(DecimalPrecision.round(-1.005, 2) === -1.01); console.log(DecimalPrecision.round(-39.425, 2) === -39.43); // testing edge cases for ceil console.log(DecimalPrecision.ceil(9.13, 2) === 9.13); console.log(DecimalPrecision.ceil(65.18, 2) === 65.18); console.log(DecimalPrecision.ceil(-2.26, 2) === -2.26); console.log(DecimalPrecision.ceil(-18.15, 2) === -18.15); // testing edge cases for floor console.log(DecimalPrecision.floor(2.26, 2) === 2.26); console.log(DecimalPrecision.floor(18.15, 2) === 18.15); console.log(DecimalPrecision.floor(-9.13, 2) === -9.13); console.log(DecimalPrecision.floor(-65.18, 2) === -65.18); // testing edge cases for trunc console.log(DecimalPrecision.trunc(2.26, 2) === 2.26); console.log(DecimalPrecision.trunc(18.15, 2) === 18.15); console.log(DecimalPrecision.trunc(-2.26, 2) === -2.26); console.log(DecimalPrecision.trunc(-18.15, 2) === -18.15); // testing round to tens and hundreds console.log(DecimalPrecision.round(1262.48, -1) === 1260); console.log(DecimalPrecision.round(1262.48, -2) === 1300); // testing toFixed() console.log(DecimalPrecision.toFixed(1.005, 2) === "1.01");

Solution 2: purely mathematical (Number.EPSILON)

This solution avoids any string conversion / manipulation of any kind for performance reasons.

// Solution 2 var DecimalPrecision2 = (function() { if (Number.EPSILON === undefined) { Number.EPSILON = Math.pow(2, -52); } if (Math.trunc === undefined) { Math.trunc = function(v) { return v < 0 ? Math.ceil(v) : Math.floor(v); }; } var powers = [ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 ]; var intpow10 = function(power) { if (power < 0 || power > 22) { return Math.pow(10, power); } return powers[power]; }; var isRound = function(num, decimalPlaces) { //return decimalPlaces >= 0 && // +num.toFixed(decimalPlaces) === num; var p = intpow10(decimalPlaces); return Math.round(num * p) / p === num; }; var decimalAdjust = function(type, num, decimalPlaces) { if (type !== 'round' && isRound(num, decimalPlaces || 0)) return num; var p = intpow10(decimalPlaces || 0); var n = (num * p) * (1 + Number.EPSILON); return Math[type](n) / p; }; return { // Decimal round (half away from zero) round: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces); }, // Decimal ceil ceil: function(num, decimalPlaces) { return decimalAdjust('ceil', num, decimalPlaces); }, // Decimal floor floor: function(num, decimalPlaces) { return decimalAdjust('floor', num, decimalPlaces); }, // Decimal trunc trunc: function(num, decimalPlaces) { return decimalAdjust('trunc', num, decimalPlaces); }, // Format using fixed-point notation toFixed: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces).toFixed(decimalPlaces); } }; })(); // test rounding of half console.log(DecimalPrecision2.round(0.5)); // 1 console.log(DecimalPrecision2.round(-0.5)); // -1 // testing very small numbers console.log(DecimalPrecision2.ceil(1e-8, 2) === 0.01); console.log(DecimalPrecision2.floor(1e-8, 2) === 0); // testing simple cases console.log(DecimalPrecision2.round(5.12, 1) === 5.1); console.log(DecimalPrecision2.round(-5.12, 1) === -5.1); console.log(DecimalPrecision2.ceil(5.12, 1) === 5.2); console.log(DecimalPrecision2.ceil(-5.12, 1) === -5.1); console.log(DecimalPrecision2.floor(5.12, 1) === 5.1); console.log(DecimalPrecision2.floor(-5.12, 1) === -5.2); console.log(DecimalPrecision2.trunc(5.12, 1) === 5.1); console.log(DecimalPrecision2.trunc(-5.12, 1) === -5.1); // testing edge cases for round console.log(DecimalPrecision2.round(1.005, 2) === 1.01); console.log(DecimalPrecision2.round(39.425, 2) === 39.43); console.log(DecimalPrecision2.round(-1.005, 2) === -1.01); console.log(DecimalPrecision2.round(-39.425, 2) === -39.43); // testing edge cases for ceil console.log(DecimalPrecision2.ceil(9.13, 2) === 9.13); console.log(DecimalPrecision2.ceil(65.18, 2) === 65.18); console.log(DecimalPrecision2.ceil(-2.26, 2) === -2.26); console.log(DecimalPrecision2.ceil(-18.15, 2) === -18.15); // testing edge cases for floor console.log(DecimalPrecision2.floor(2.26, 2) === 2.26); console.log(DecimalPrecision2.floor(18.15, 2) === 18.15); console.log(DecimalPrecision2.floor(-9.13, 2) === -9.13); console.log(DecimalPrecision2.floor(-65.18, 2) === -65.18); // testing edge cases for trunc console.log(DecimalPrecision2.trunc(2.26, 2) === 2.26); console.log(DecimalPrecision2.trunc(18.15, 2) === 18.15); console.log(DecimalPrecision2.trunc(-2.26, 2) === -2.26); console.log(DecimalPrecision2.trunc(-18.15, 2) === -18.15); // testing round to tens and hundreds console.log(DecimalPrecision2.round(1262.48, -1) === 1260); console.log(DecimalPrecision2.round(1262.48, -2) === 1300); // testing toFixed() console.log(DecimalPrecision2.toFixed(1.005, 2) === "1.01");

Solution 3: double rounding

This solution uses the toPrecision() method to strip the floating-point round-off errors.

// Solution 3 var DecimalPrecision3 = (function() { if (Math.trunc === undefined) { Math.trunc = function(v) { return v < 0 ? Math.ceil(v) : Math.floor(v); }; } var powers = [ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 ]; var intpow10 = function(power) { if (power < 0 || power > 22) { return Math.pow(10, power); } return powers[power]; }; // Eliminate binary floating-point inaccuracies. var stripError = function(num) { if (Number.isInteger(num)) return num; return parseFloat(num.toPrecision(15)); }; var decimalAdjust = function myself(type, num, decimalPlaces) { if (type === 'round' && num < 0) return -myself(type, -num, decimalPlaces); var p = intpow10(decimalPlaces || 0); var n = stripError(num * p); return Math[type](n) / p; }; return { // Decimal round (half away from zero) round: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces); }, // Decimal ceil ceil: function(num, decimalPlaces) { return decimalAdjust('ceil', num, decimalPlaces); }, // Decimal floor floor: function(num, decimalPlaces) { return decimalAdjust('floor', num, decimalPlaces); }, // Decimal trunc trunc: function(num, decimalPlaces) { return decimalAdjust('trunc', num, decimalPlaces); }, // Format using fixed-point notation toFixed: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces).toFixed(decimalPlaces); } }; })(); // test rounding of half console.log(DecimalPrecision3.round(0.5)); // 1 console.log(DecimalPrecision3.round(-0.5)); // -1 // testing very small numbers console.log(DecimalPrecision3.ceil(1e-8, 2) === 0.01); console.log(DecimalPrecision3.floor(1e-8, 2) === 0); // testing simple cases console.log(DecimalPrecision3.round(5.12, 1) === 5.1); console.log(DecimalPrecision3.round(-5.12, 1) === -5.1); console.log(DecimalPrecision3.ceil(5.12, 1) === 5.2); console.log(DecimalPrecision3.ceil(-5.12, 1) === -5.1); console.log(DecimalPrecision3.floor(5.12, 1) === 5.1); console.log(DecimalPrecision3.floor(-5.12, 1) === -5.2); console.log(DecimalPrecision3.trunc(5.12, 1) === 5.1); console.log(DecimalPrecision3.trunc(-5.12, 1) === -5.1); // testing edge cases for round console.log(DecimalPrecision3.round(1.005, 2) === 1.01); console.log(DecimalPrecision3.round(39.425, 2) === 39.43); console.log(DecimalPrecision3.round(-1.005, 2) === -1.01); console.log(DecimalPrecision3.round(-39.425, 2) === -39.43); // testing edge cases for ceil console.log(DecimalPrecision3.ceil(9.13, 2) === 9.13); console.log(DecimalPrecision3.ceil(65.18, 2) === 65.18); console.log(DecimalPrecision3.ceil(-2.26, 2) === -2.26); console.log(DecimalPrecision3.ceil(-18.15, 2) === -18.15); // testing edge cases for floor console.log(DecimalPrecision3.floor(2.26, 2) === 2.26); console.log(DecimalPrecision3.floor(18.15, 2) === 18.15); console.log(DecimalPrecision3.floor(-9.13, 2) === -9.13); console.log(DecimalPrecision3.floor(-65.18, 2) === -65.18); // testing edge cases for trunc console.log(DecimalPrecision3.trunc(2.26, 2) === 2.26); console.log(DecimalPrecision3.trunc(18.15, 2) === 18.15); console.log(DecimalPrecision3.trunc(-2.26, 2) === -2.26); console.log(DecimalPrecision3.trunc(-18.15, 2) === -18.15); // testing round to tens and hundreds console.log(DecimalPrecision3.round(1262.48, -1) === 1260); console.log(DecimalPrecision3.round(1262.48, -2) === 1300); // testing toFixed() console.log(DecimalPrecision3.toFixed(1.005, 2) === "1.01");

Solution 4: double rounding v2

This solution is just like Solution 3, however it uses a custom toPrecision() function.

// Solution 4 var DecimalPrecision4 = (function() { if (Math.trunc === undefined) { Math.trunc = function(v) { return v < 0 ? Math.ceil(v) : Math.floor(v); }; } var powers = [ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22 ]; var intpow10 = function(power) { if (power < 0 || power > 22) { return Math.pow(10, power); } return powers[power]; }; var toPrecision = function(num, significantDigits) { // Return early for ±0, NaN and Infinity. if (!num || !Number.isFinite(num)) return num; // Compute shift of the decimal point (sf - leftSidedDigits). var shift = significantDigits - 1 - Math.floor(Math.log10(Math.abs(num))); // Return if rounding to the same or higher precision. var decimalPlaces = 0; for (var p = 1; num != Math.round(num * p) / p; p *= 10) decimalPlaces++; if (shift >= decimalPlaces) return num; // Round to "shift" fractional digits var scale = intpow10(Math.abs(shift)); return shift > 0 ? Math.round(num * scale) / scale : Math.round(num / scale) * scale; }; // Eliminate binary floating-point inaccuracies. var stripError = function(num) { if (Number.isInteger(num)) return num; return toPrecision(num, 15); }; var decimalAdjust = function myself(type, num, decimalPlaces) { if (type === 'round' && num < 0) return -myself(type, -num, decimalPlaces); var p = intpow10(decimalPlaces || 0); var n = stripError(num * p); return Math[type](n) / p; }; return { // Decimal round (half away from zero) round: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces); }, // Decimal ceil ceil: function(num, decimalPlaces) { return decimalAdjust('ceil', num, decimalPlaces); }, // Decimal floor floor: function(num, decimalPlaces) { return decimalAdjust('floor', num, decimalPlaces); }, // Decimal trunc trunc: function(num, decimalPlaces) { return decimalAdjust('trunc', num, decimalPlaces); }, // Format using fixed-point notation toFixed: function(num, decimalPlaces) { return decimalAdjust('round', num, decimalPlaces).toFixed(decimalPlaces); } }; })(); // test rounding of half console.log(DecimalPrecision4.round(0.5)); // 1 console.log(DecimalPrecision4.round(-0.5)); // -1 // testing very small numbers console.log(DecimalPrecision4.ceil(1e-8, 2) === 0.01); console.log(DecimalPrecision4.floor(1e-8, 2) === 0); // testing simple cases console.log(DecimalPrecision4.round(5.12, 1) === 5.1); console.log(DecimalPrecision4.round(-5.12, 1) === -5.1); console.log(DecimalPrecision4.ceil(5.12, 1) === 5.2); console.log(DecimalPrecision4.ceil(-5.12, 1) === -5.1); console.log(DecimalPrecision4.floor(5.12, 1) === 5.1); console.log(DecimalPrecision4.floor(-5.12, 1) === -5.2); console.log(DecimalPrecision4.trunc(5.12, 1) === 5.1); console.log(DecimalPrecision4.trunc(-5.12, 1) === -5.1); // testing edge cases for round console.log(DecimalPrecision4.round(1.005, 2) === 1.01); console.log(DecimalPrecision4.round(39.425, 2) === 39.43); console.log(DecimalPrecision4.round(-1.005, 2) === -1.01); console.log(DecimalPrecision4.round(-39.425, 2) === -39.43); // testing edge cases for ceil console.log(DecimalPrecision4.ceil(9.13, 2) === 9.13); console.log(DecimalPrecision4.ceil(65.18, 2) === 65.18); console.log(DecimalPrecision4.ceil(-2.26, 2) === -2.26); console.log(DecimalPrecision4.ceil(-18.15, 2) === -18.15); // testing edge cases for floor console.log(DecimalPrecision4.floor(2.26, 2) === 2.26); console.log(DecimalPrecision4.floor(18.15, 2) === 18.15); console.log(DecimalPrecision4.floor(-9.13, 2) === -9.13); console.log(DecimalPrecision4.floor(-65.18, 2) === -65.18); // testing edge cases for trunc console.log(DecimalPrecision4.trunc(2.26, 2) === 2.26); console.log(DecimalPrecision4.trunc(18.15, 2) === 18.15); console.log(DecimalPrecision4.trunc(-2.26, 2) === -2.26); console.log(DecimalPrecision4.trunc(-18.15, 2) === -18.15); // testing round to tens and hundreds console.log(DecimalPrecision4.round(1262.48, -1) === 1260); console.log(DecimalPrecision4.round(1262.48, -2) === 1300); // testing toFixed() console.log(DecimalPrecision4.toFixed(1.005, 2) === "1.01");

Benchmarks

//jsbench.github.io/#31ec3a8b3d22bd840f8e6822e681a3ac

Here is a benchmark comparing the operations per second in the solutions above on Chrome 85.0.4183.83. Obviously all browsers differ, so your mileage may vary.

(Note: More is better)

Thanks @Mike for adding a screenshot of the benchmark.

How do I round to a specific decimal in JavaScript?

JavaScript Number toFixed() The toFixed() method converts a number to a string. The toFixed() method rounds the string to a specified number of decimals.

How do you round a number to 2 decimal places in JavaScript?

Use the toFixed() method to round a number to 2 decimal places, e.g. const result = num. toFixed(2) . The toFixed method will round and format the number to 2 decimal places.

How do you control decimal places in JavaScript?

To limit decimal places in JavaScript, use the toFixed() method by specifying the number of decimal places..

Rounds the number..

Converts it into a string..

Returns the number as a string..

Chủ đề