# Formatting a number with exactly two decimals in JavaScript

## Formatting a number with exactly two decimals in JavaScript

I have this line of code which rounds my numbers to two decimal places. But I get numbers like this: 10.8, 2.4, etc. These are not my idea of two decimal places so how I can improve the following?
Math.round(price*Math.pow(10,2))/Math.pow(10,2);

I want numbers like 10.80, 2.40, etc. Use of jQuery is fine with me.

## Solutions/Answers:

### Solution 1:

To format a number using fixed-point notation, you can simply use the toFixed method:

``````(10.8).toFixed(2); // "10.80"

var num = 2.4;
alert(num.toFixed(2)); // "2.40"
``````

Note that `toFixed()` returns a string.

IMPORTANT: Note that toFixed does not actually round, 90% of the time, it will return the rounded value but for many cases it doesn’t actually work. Try this in your console:

`2.005.toFixed(2)`

You will get the wrong answer

There is no natural way of getting a decimal rounding in javascript, you will need your own polyfill or use a library. You can look at mozilla’s polyfill for this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round

### Solution 2:

This is an old topic but still top-ranked Google results and the solutions offered share the same floating point decimals issue. Here is the (very generic) function I use, thanks to MDN:

``````function round(value, exp) {
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);

value = +value;
exp = +exp;

if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;

// Shift
value = value.toString().split('e');
value = Math.round(+(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));
}
``````

As we can see, we don’t get these issues:

``````round(1.275, 2);   // Returns 1.28
round(1.27499, 2); // Returns 1.27
``````

This genericity also provides some cool stuff:

``````round(1234.5678, -2);   // Returns 1200
round(1.2345678e+2, 2); // Returns 123.46
round("123.45");        // Returns 123
``````

Now, to answer the OP’s question, one has to type:

``````round(10.8034, 2).toFixed(2); // Returns "10.80"
round(10.8, 2).toFixed(2);    // Returns "10.80"
``````

Or, for a more concise, less generic function:

``````function round2Fixed(value) {
value = +value;

if (isNaN(value))
return NaN;

// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + 2) : 2)));

// Shift back
value = value.toString().split('e');
return (+(value[0] + 'e' + (value[1] ? (+value[1] - 2) : -2))).toFixed(2);
}
``````

You can call it with:

``````round2Fixed(10.8034); // Returns "10.80"
round2Fixed(10.8);    // Returns "10.80"
``````

Various examples and tests (thanks to @t-j-crowder!):

``````function round(value, exp) {
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);

value = +value;
exp = +exp;

if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;

// Shift
value = value.toString().split('e');
value = Math.round(+(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));
}
function naive(value, exp) {
if (!exp) {
return Math.round(value);
}
var pow = Math.pow(10, exp);
return Math.round(value * pow) / pow;
}
function test(val, places) {
subtest(val, places);
val = typeof val === "string" ? "-" + val : -val;
subtest(val, places);
}
function subtest(val, places) {
var placesOrZero = places || 0;
var naiveResult = naive(val, places);
var roundResult = round(val, places);
if (placesOrZero >= 0) {
naiveResult = naiveResult.toFixed(placesOrZero);
roundResult = roundResult.toFixed(placesOrZero);
} else {
naiveResult = naiveResult.toString();
roundResult = roundResult.toString();
}
\$("<tr>")
.append(\$("<td>").text(JSON.stringify(val)))
.append(\$("<td>").text(placesOrZero))
.append(\$("<td>").text(naiveResult))
.append(\$("<td>").text(roundResult))
.appendTo("#results");
}
test(0.565, 2);
test(0.575, 2);
test(0.585, 2);
test(1.275, 2);
test(1.27499, 2);
test(1234.5678, -2);
test(1.2345678e+2, 2);
test("123.45");
test(10.8034, 2);
test(10.8, 2);
test(1.005, 2);
test(1.0005, 2);``````
``````table {
border-collapse: collapse;
}
table, td, th {
border: 1px solid #ddd;
}
td, th {
padding: 4px;
}
th {
font-weight: normal;
font-family: sans-serif;
}
td {
font-family: monospace;
}``````
``````<table>
<thead>
<tr>
<th>Input</th>
<th>Places</th>
<th>Naive</th>
<th>Thorough</th>
</tr>
</thead>
<tbody id="results">
</tbody>
</table>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>``````

### Solution 3:

I usually add this to my personal library, and after some suggestions and using the @TIMINeutron solution too, and making it adaptable for decimal length then, this one fits best:

``````function precise_round(num, decimals) {
var t = Math.pow(10, decimals);
return (Math.round((num * t) + (decimals>0?1:0)*(Math.sign(num) * (10 / Math.pow(100, decimals)))) / t).toFixed(decimals);
}
``````

will work for the exceptions reported.

### Solution 4:

I don’t know why can’t I add a comment to a previous answer (maybe I’m hopelessly blind, dunno), but I came up with a solution using @Miguel’s answer:

``````function precise_round(num,decimals) {
return Math.round(num*Math.pow(10, decimals)) / Math.pow(10, decimals);
}
``````

And its two comments (from @bighostkim and @Imre):

• Problem with `precise_round(1.275,2)` not returning 1.28
• Problem with `precise_round(6,2)` not returning 6.00 (as he wanted).

My final solution is as follows:

``````function precise_round(num,decimals) {
var sign = num >= 0 ? 1 : -1;
return (Math.round((num*Math.pow(10,decimals)) + (sign*0.001)) / Math.pow(10,decimals)).toFixed(decimals);
}
``````

As you can see I had to add a little bit of “correction” (it’s not what it is, but since Math.round is lossy – you can check it on jsfiddle.net – this is the only way I knew how to “fix” it). It adds 0.001 to the already padded number, so it is adding a `1` three `0`s to the right of the decimal value. So it should be safe to use.

After that I added `.toFixed(decimal)` to always output the number in the correct format (with the right amount of decimals).

So that’s pretty much it. Use it well 😉

EDIT: added functionality to the “correction” of negative numbers.

### Solution 5:

One way to be 100% sure that you get a number with 2 decimals:

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

If this causes rounding errors, you can use the following as James has explained in his comment:

``````(Math.round((num * 1000)/10)/100).toFixed(2)
``````

### Solution 6:

toFixed(n) provides n length after the decimal point; toPrecision(x)
provides x total length.

Use this method below

``````// Example: toPrecision(4) when the number has 7 digits (3 before, 4 after)
// It will round to the tenths place
num = 500.2349;
result = num.toPrecision(4); // result will equal 500.2
``````

AND if you want the number to be fixed use

``````result = num.toFixed(2);
``````