# javascript - How to round to at most 2 decimal places, if necessary?

ID : 138

viewed : 24

### Top 5 Answer for javascript - How to round to at most 2 decimal places, if necessary?  99

``Math.round(num * 100) / 100 ``

Or to be more specific and to ensure things like 1.005 round correctly, use Number.EPSILON :

``Math.round((num + Number.EPSILON) * 100) / 100 ``  90

If the value is a text type:

``parseFloat("123.456").toFixed(2); ``

If the value is a number:

``var numb = 123.23454; numb = numb.toFixed(2); ``

There is a downside that values like 1.5 will give "1.50" as the output. A fix suggested by @minitech:

``var numb = 1.5; numb = +numb.toFixed(2); // Note the plus sign that drops any "extra" zeroes at the end. // It changes the result (which is a string) into a number again (think "0 + foo"), // which means that it uses only as many digits as necessary. ``

It seems like `Math.round` is a better solution. But it is not! In some cases it will NOT round correctly:

``Math.round(1.005 * 100)/100 // Returns 1 instead of expected 1.01! ``

toFixed() will also NOT round correctly in some cases (tested in Chrome v.55.0.2883.87)!

Examples:

``parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56. parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56. // However, it will return correct result if you round 1.5551. parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.  1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356. // However, it will return correct result if you round 1.35551. 1.35551.toFixed(2); // Returns 1.36 as expected. ``

I guess, this is because 1.555 is actually something like float 1.55499994 behind the scenes.

Solution 1 is to use a script with required rounding algorithm, for example:

``function roundNumber(num, scale) {   if(!("" + num).includes("e")) {     return +(Math.round(num + "e+" + scale)  + "e-" + scale);   } else {     var arr = ("" + num).split("e");     var sig = ""     if(+arr + scale > 0) {       sig = "+";     }     return +(Math.round(+arr + "e" + sig + (+arr + scale)) + "e-" + scale);   } } ``

https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview

NOTE: This is not a universal solution for everyone. There are several different rounding algorithms, your implementation can be different, depends on your requirements. https://en.wikipedia.org/wiki/Rounding

Solution 2 is to avoid front end calculations and pull rounded values from the backend server.

Edit: Another possible solution, which is not a bullet proof also.

``Math.round((num + Number.EPSILON) * 100) / 100 ``

In some cases, when you round number like 1.3549999999999998 it will return incorrect result. Should be 1.35 but result is 1.36.  77

You can use

``function roundToTwo(num) {         return +(Math.round(num + "e+2")  + "e-2"); } ``

I found this over on MDN. Their way avoids the problem with 1.005 that was mentioned.

``roundToTwo(1.005) 1.01 roundToTwo(10) 10 roundToTwo(1.7777777) 1.78 roundToTwo(9.1) 9.1 roundToTwo(1234.5678) 1234.57 ``  70

MarkG's answer is the correct one. Here's a generic extension for any number of decimal places.

``Number.prototype.round = function(places) {   return +(Math.round(this + "e+" + places)  + "e-" + places); } ``

Usage:

``var n = 1.7777;     n.round(2); // 1.78 ``

Unit test:

``it.only('should round floats to 2 places', function() {    var cases = [     { n: 10,      e: 10,    p:2 },     { n: 1.7777,  e: 1.78,  p:2 },     { n: 1.005,   e: 1.01,  p:2 },     { n: 1.005,   e: 1,     p:0 },     { n: 1.77777, e: 1.8,   p:1 }   ]    cases.forEach(function(testCase) {     var r = testCase.n.round(testCase.p);     assert.equal(r, testCase.e, 'didn\'t get right number');   }); }) ``  55

You should use:

``Math.round( num * 100 + Number.EPSILON ) / 100 ``

No one seems to be aware of `Number.EPSILON`.

Also it's worth noting that this is not a JavaScript weirdness like some people stated.

That is simply the way floating point numbers works in a computer. Like 99% of programming languages, JavaScript doesn't have home made floating point numbers; it relies on the CPU/FPU for that. A computer uses binary, and in binary, there isn't any numbers like `0.1`, but a mere binary approximation for that. Why? For the same reason than 1/3 cannot be written in decimal: its value is 0.33333333... with an infinity of threes.

Here come `Number.EPSILON`. That number is the difference between 1 and the next number existing in the double precision floating point numbers. That's it: There is no number between `1` and 1 + `Number.EPSILON`.

EDIT:

As asked in the comments, let's clarify one thing: adding `Number.EPSILON` is relevant only when the value to round is the result of an arithmetic operation, as it can swallow some floating point error delta.

It's not useful when the value comes from a direct source (e.g.: literal, user input or sensor).

EDIT (2019):

Like @maganap and some peoples have pointed out, it's best to add `Number.EPSILON` before multiplying:

``Math.round( ( num + Number.EPSILON ) * 100 ) / 100 ``

EDIT (december 2019):

Lately, I use a function similar to this one for comparing numbers epsilon-aware:

``const ESPILON_RATE = 1 + Number.EPSILON ; const ESPILON_ZERO = Number.MIN_VALUE ;  function epsilonEquals( a , b ) {   if ( Number.isNaN( a ) || Number.isNaN( b ) ) {     return false ;   }   if ( a === 0 || b === 0 ) {     return a <= b + EPSILON_ZERO && b <= a + EPSILON_ZERO ;   }   return a <= b * EPSILON_RATE && b <= a * EPSILON_RATE ; } ``

My use-case is an assertion + data validation lib I'm developing for many years.

In fact, in the code I'm using `ESPILON_RATE = 1 + 4 * Number.EPSILON` and `EPSILON_ZERO = 4 * Number.MIN_VALUE` (four times the epsilon), because I want an equality checker loose enough for cumulating floating point error.

So far, it looks perfect for me. I hope it will help.