# javascript math.round up - Round to at most 2 decimal places (only if necessary)

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 * 1000)/1000 // Returns 1 instead of expected 1.01!
``````

toFixed() also will 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[1] + scale > 0) {
sig = "+";
}
return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
}
}
``````

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

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

format number decimals

I'd like to round at most 2 decimal places, but only if necessary.

Input:

``````10
1.7777777
9.1
``````

Output:

``````10
1.78
9.1
``````

How can I do this in `JavaScript`?

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');
});
})
``````

A precise rounding method. Source: Mozilla

``````(function(){

/**
* Decimal adjustment of a number.
*
* @param   {String}    type    The type of adjustment.
* @param   {Number}    value   The number.
* @param   {Integer}   exp     The exponent (the 10 logarithm of the adjustment base).
* @returns {Number}            The adjusted value.
*/
// If the exp is undefined or zero...
if (typeof exp === 'undefined' || +exp === 0) {
return Math[type](value);
}
value = +value;
exp = +exp;
// If the value is not a number or the exp is not an integer...
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
return NaN;
}
// Shift
value = value.toString().split('e');
value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}

// Decimal round
if (!Math.round10) {
Math.round10 = function(value, exp) {
};
}
// Decimal floor
if (!Math.floor10) {
Math.floor10 = function(value, exp) {
};
}
// Decimal ceil
if (!Math.ceil10) {
Math.ceil10 = function(value, exp) {
};
}
})();
``````

Examples:

``````// Round
Math.round10(55.55, -1); // 55.6
Math.round10(55.549, -1); // 55.5
Math.round10(55, 1); // 60
Math.round10(54.9, 1); // 50
Math.round10(-55.55, -1); // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1); // -50
Math.round10(-55.1, 1); // -60
Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005*100)/100 above
// Floor
Math.floor10(55.59, -1); // 55.5
Math.floor10(59, 1); // 50
Math.floor10(-55.51, -1); // -55.6
Math.floor10(-51, 1); // -60
// Ceil
Math.ceil10(55.51, -1); // 55.6
Math.ceil10(51, 1); // 60
Math.ceil10(-55.59, -1); // -55.5
Math.ceil10(-59, 1); // -50
``````

None of the answers found here is correct. @stinkycheeseman asked to round up, you all rounded the number.

To round up, use this:

``````Math.ceil(num * 100)/100;
``````

Here is a simple way to do it:

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

You might want to go ahead and make a separate function to do it for you though:

``````function roundToTwo(value) {
return(Math.round(value * 100) / 100);
}
``````

Then you would simply pass in the value.

You could enhance it to round to any arbitrary number of decimals by adding a second parameter.

``````function myRound(value, places) {
var multiplier = Math.pow(10, places);

return (Math.round(value * multiplier) / multiplier);
}
``````

``````+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12
``````

Try this light weight solution:

``````function round(x, digits){
return parseFloat(x.toFixed(digits))
}

round(1.222,  2) ;
// 1.22
round(1.222, 10) ;
// 1.222
``````

There are a couple of ways to do that. For people like me, the Lodash's variant

``````function round(number, precision) {
var pair = (number + 'e').split('e')
var value = Math.round(pair[0] + 'e' + (+pair[1] + precision))
pair = (value + 'e').split('e')
return +(pair[0] + 'e' + (+pair[1] - precision))
}
``````

Usage:

``````round(0.015, 2) // 0.02
round(1.005, 2) // 1.01
``````

If your project uses jQuery or lodash, you can also find proper `round` method in the libraries.

## Update 1

I removed the variant `n.toFixed(2)`, because it is not correct. Thank you @avalanche1

``````var roundUpto = function(number, upto){
return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);
``````

`toFixed(2)` here 2 is number of digits upto which we want to round this num.

Use something like this "parseFloat(parseFloat(value).toFixed(2))"

``````parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78
parseFloat(parseFloat("10").toFixed(2))-->10
parseFloat(parseFloat("9.1").toFixed(2))-->9.1
``````

To not deal with many 0s, use this variant:

``````Math.round(num * 1e2) / 1e2
``````

One way to achieve such a rounding only if necessary is to use Number.prototype.toLocaleString():

``````myNumber.toLocaleString('en', {maximumFractionDigits:2, useGrouping:false})
``````

This will provide exactly the output you expect, but as strings. You can still convert those back to numbers if that's not the data type you expect.

Since ES6 there is a 'proper' way (without overriding statics and creating workarounds) to do this by using toPrecision

``````var x = 1.49999999999;
console.log(x.toPrecision(4));
console.log(x.toPrecision(3));
console.log(x.toPrecision(2));

var y = Math.PI;
console.log(y.toPrecision(6));
console.log(y.toPrecision(5));
console.log(y.toPrecision(4));

var z = 222.987654
console.log(z.toPrecision(6));
console.log(z.toPrecision(5));
console.log(z.toPrecision(4));``````

### Tags

javascript   decimal   rounding   decimal-point