# 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.

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;
``````

Note that `toFixed()` returns a string.

IMPORTANT: Note that toFixed does not actually round, for 90% of the case, it will return the rounded value but for many cases it doesnt 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

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

@heridev and I created a small function in jQuery.

You can try next:

HTML

``````<input type="text" name="one" class="two-digits"><br>
<input type="text" name="two" class="two-digits">​
``````

jQuery

``````// apply the two-digits behaviour to elements with 'two-digits' as their class
\$( function() {
\$('.two-digits').keyup(function(){
if(\$(this).val().indexOf('.')!=-1){
if(\$(this).val().split(".")[1].length > 2){
if( isNaN( parseFloat( this.value ) ) ) return;
this.value = parseFloat(this.value).toFixed(2);
}
}
return this; //for chaining
});
});
``````

​ DEMO ONLINE:

http://jsfiddle.net/c4Wqn/

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.

The trouble with floating point values is that they are trying to represent an infinite amount of (continuous) values with a fixed amount of bits. So naturally, there must be some loss in play, and you're going to be bitten with some values.

When a computer stores 1.275 as a floating point value, it won't actually remember whether it was 1.275 or 1.27499999999999993, or even 1.27500000000000002. These values should give different results after rounding to two decimals, but they won't, since for computer they look exactly the same after storing as floating point values, and there's no way to restore the lost data. Any further calculations will only accumulate such imprecision.

So, if precision matters, you have to avoid floating point values from the start. The simplest options are to

• use a devoted library
• use strings for storing and passing around the values (accompanied by string operations)
• use integers (e.g. you could be passing around the amount of hundredths of your actual value, e.g. amount in cents instead of amount in dollars)

For example, when using integers to store the number of hundredths, the function for finding the actual value is quite simple:

``````function descale(num, decimals) {
var hasMinus = num < 0;
var numString = Math.abs(num).toString();
var precedingZeroes = '';
for (var i = numString.length; i <= decimals; i++) {
precedingZeroes += '0';
}
numString = precedingZeroes + numString;
return (hasMinus ? '-' : '')
+ numString.substr(0, numString.length-decimals)
+ '.'
+ numString.substr(numString.length-decimals);
}

``````

With strings, you'll need rounding, but it's still manageable:

``````function precise_round(num, decimals) {
var parts = num.split('.');
var hasMinus = parts.length > 0 && parts[0].length > 0 && parts[0].charAt(0) == '-';
var integralPart = parts.length == 0 ? '0' : (hasMinus ? parts[0].substr(1) : parts[0]);
var decimalPart = parts.length > 1 ? parts[1] : '';
if (decimalPart.length > decimals) {
var roundOffNumber = decimalPart.charAt(decimals);
decimalPart = decimalPart.substr(0, decimals);
if ('56789'.indexOf(roundOffNumber) > -1) {
var numbers = integralPart + decimalPart;
var i = numbers.length;
var trailingZeroes = '';
var justOneAndTrailingZeroes = true;
do {
i--;
var roundedNumber = '1234567890'.charAt(parseInt(numbers.charAt(i)));
if (roundedNumber === '0') {
trailingZeroes += '0';
} else {
numbers = numbers.substr(0, i) + roundedNumber + trailingZeroes;
justOneAndTrailingZeroes = false;
break;
}
} while (i > 0);
if (justOneAndTrailingZeroes) {
numbers = '1' + trailingZeroes;
}
integralPart = numbers.substr(0, numbers.length - decimals);
decimalPart = numbers.substr(numbers.length - decimals);
}
} else {
for (var i = decimalPart.length; i < decimals; i++) {
decimalPart += '0';
}
}
return (hasMinus ? '-' : '') + integralPart + (decimals > 0 ? '.' + decimalPart : '');
}

``````

Note that this function rounds to nearest, ties away from zero, while IEEE 754 recommends rounding to nearest, ties to even as the default behavior for floating point operations. Such modifications are left as an exercise for the reader :)

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.

Here's a simple one

``````function roundFloat(num,dec){
var d = 1;
for (var i=0; i<dec; i++){
d += "0";
}
return Math.round(num * d) / d;
}
``````

Use like `alert(roundFloat(1.79209243929,4));`

Jsfiddle

Round your decimal value, then use `toFixed(x)` for your expected digit(s).

``````function parseDecimalRoundAndFixed(num,dec){
var d =  Math.pow(10,dec);
return (Math.round(num * d) / d).toFixed(dec);
}
``````

Call

parseDecimalRoundAndFixed(10.800243929,4) => 10.80 parseDecimalRoundAndFixed(10.807243929,2) => 10.81

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)
``````

Put the following in some global scope:

``````Number.prototype.getDecimals = function ( decDigCount ) {
return this.toFixed(decDigCount);
}
``````

and then try:

``````var a = 56.23232323;
a.getDecimals(2); // will return 56.23
``````

## Update

Note that `toFixed()` can only work for the number of decimals between `0-20` i.e. `a.getDecimals(25)` may generate a javascript error, so to accomodate that you may add some additional check i.e.

``````Number.prototype.getDecimals = function ( decDigCount ) {
return ( decDigCount > 20 ) ? this : this.toFixed(decDigCount);
}
``````