Javascript: formatting a rounded number to N decimals
Solution 1
That's not a rounding ploblem, that is a display problem. A number doesn't contain information about significant digits; the value 2 is the same as 2.0000000000000. It's when you turn the rounded value into a string that you have make it display a certain number of digits.
You could just add zeroes after the number, something like:
var s = number.toString();
if (s.indexOf('.') == -1) s += '.';
while (s.length < s.indexOf('.') + 4) s += '0';
(Note that this assumes that the regional settings of the client uses period as decimal separator, the code needs some more work to function for other settings.)
Solution 2
I think that there is a more simple approach to all given here, and is the method Number.toFixed()
already implemented in JavaScript.
simply write:
var myNumber = 2;
myNumber.toFixed(2); //returns "2.00"
myNumber.toFixed(1); //returns "2.0"
etc...
Solution 3
I found a way. This is Christoph's code with a fix:
function toFixed(value, precision) {
var precision = precision || 0,
power = Math.pow(10, precision),
absValue = Math.abs(Math.round(value * power)),
result = (value < 0 ? '-' : '') + String(Math.floor(absValue / power));
if (precision > 0) {
var fraction = String(absValue % power),
padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');
result += '.' + padding + fraction;
}
return result;
}
Read the details of repeating a character using an array constructor here if you are curious as to why I added the "+ 1".
Solution 4
There's always a better way for doing things. Use toPrecision -
var number = 51.93999999999761;
I would like to get four digits precision: 51.94
just do:
number.toPrecision(4);
the result will be: 51.94
Solution 5
PHP-Like rounding Method
The code below can be used to add your own version of Math.round to your own namespace which takes a precision parameter. Unlike Decimal rounding in the example above, this performs no conversion to and from strings, and the precision parameter works same way as PHP and Excel whereby a positive 1 would round to 1 decimal place and -1 would round to the tens.
var myNamespace = {};
myNamespace.round = function(number, precision) {
var factor = Math.pow(10, precision);
var tempNumber = number * factor;
var roundedTempNumber = Math.round(tempNumber);
return roundedTempNumber / factor;
};
myNamespace.round(1234.5678, 1); // 1234.6
myNamespace.round(1234.5678, -1); // 1230
Related videos on Youtube
Comments
-
hoju almost 2 years
in JavaScript, the typical way to round a number to N decimal places is something like:
function roundNumber(num, dec) { return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); }
function roundNumber(num, dec) { return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); } console.log(roundNumber(0.1 + 0.2, 2)); console.log(roundNumber(2.1234, 2));
However this approach will round to a maximum of N decimal places while I want to always round to N decimal places. For example "2.0" would be rounded to "2".
Any ideas?
-
Christoph about 14 yearsnormally, you could use
toFixed()
( developer.mozilla.org/En/Core_JavaScript_1.5_Reference/… ), but it's buggy in IE: stackoverflow.com/questions/661562/… ; you'll have to write your own version... -
robocat almost 9 years@hoju - perhaps change accepted answer - David's answer is correct for IE8+, while the accepted answer has some serious bugs on all browsers.
-
Guffa almost 9 years@robocat: Are you serious?
-
-
Elias Zamaria almost 14 yearsYour code has a bug. I tried toFixed(2.01, 4) and got a result of "2.100". If I ever find a way to fix it, I will post it as an answer to this question.
-
Christoph almost 14 years@mikez302: the padding computation was off by one; should work now, but feel free to bug me again if it's still broken...
-
Bat_Programmer over 12 yearstoFixed is buggy..for instance the decimal: 1.02449999998 if u do dec.toFixed(4) => 1.0244. It should have been 1.0245 instead.
-
pauloya over 12 years@deepeshk But what would be the problem with using
toFixed()
to pad decimals at the end, after rounding? -
Matt Ball about 12 years@deepeshk in what browser? Just tried it in Chrome 17 and
1.02449999998.toFixed(4)
correctly returns1.0245
. -
Rick Kukiela over 11 yearsVery strange. When I run this fuction with the firebug console open in firefox 17 it freezes the whole browser like js is caught in an endless loop. Even if i do not console.log the output. If I do not have firebug activated the bug does not occur.
-
Rick Kukiela over 11 yearsUpdate, i ran it in chrome and i get: Uncaught RangeError: Maximum call stack size exceeded in regards to the toFixed function call.
-
Christoph over 11 years@SublymeRick: I have no idea why this happens; shot in the dark: try renaming the function...
-
Mark Tomlin almost 11 years@Mark got most of the answer, but after some research you need to call it like this,
Number(float).toFxied(places);
. -
Guffa almost 11 years@MarkTomlin: Then it seems that you have a string instead of a number.
-
Mark Tomlin almost 11 years@Guffa thanks' for the clarification, I'm kinda fumbling my way through JavaScript programming right now. +1.
-
alan over 10 yearsPassing in a value of 708.3333333333333 with a precision of 2 or 3 results in a return value of 708.00 for me. I need this for 2 decimal places, in Chrome and IE 9 .toFixed(2) met my needs.
-
alan over 10 yearsAs an FYI, if you only need precision to 2 decimal places .toFixed works for both IE and Chrome.
-
David about 10 yearsWhere is mentioned, hoju? I reviewed other answers and I didn't find anyone reporting that toFixed function is buggy. Thanks
-
hiway almost 10 yearsthis is not a common way, e.g, toFixed(16.775, 2) return 16.77. Convert number to String then convert is the only way.
-
Matt over 9 yearsThere is a bug with this method: toFixed(-0.1111, 2) returns 0.11, i.e. the negative sign is lost.
-
Elias Zamaria over 9 yearsI tried
format(1.2, 5)
and got1.2
, while I expected1.20000
. -
Artur Barseghyan about 9 yearsWorks great, except for that I have added parseFloat(result) at the end. Worth an edit.
-
robocat almost 9 years.toFixed() works brilliantly in modern browsers (I tested Chrome, Firefox, IE11, IE8). @Bat_Programmer - please clarify which browsers you think have that bug.
-
Guffa almost 9 years@robocat: stackoverflow.com/questions/661562/…
-
robocat almost 9 years
.toFixed()
is fixed in IE8+ (my testing) but apparently buggy in IE7 (as per @Guffa link in comment above - thank you). So use toFixed() unless you need to support IE7 ;-) -
robocat almost 9 yearsDo NOT USE this answer because it has serious bugs: it gives incorrect answers: NaN -> NaN.000, Infinity -> Infinity.000, 9e60 -> 9E60.000, 0.000001 -> 0.000001 (0.000001.toFixed(3) correctly gives 0.000).
-
Guffa almost 9 years@robocat: Are you serious?
-
robocat almost 9 years@Guffa -
.toFixed()
works correctly in IE8+. e.g. I just run IE8 using the example from the link of(0.595).toFixed(2)
and got correct answer of0.60
. Your code is broken for corner cases (the few I thought of from the top of my head with a few minutes testing, I could probably find other things wrong with it), and is not suitable for production code IMHO. -
Guffa almost 9 years@robocat: You are looking for something that I never claimed that the code would be. Besdies, you can just as easily find corner cases where
toFixed
is broken, for example(1000000000000000000000).toFixed(3)
returns1e+21
not1000000000000000000000.000
. -
Guffa almost 9 years@David: That's mentioned in a comment to the answer, for example.
-
Juan Carrey almost 9 yearsSorry @EliasZamaria , didn't understand it at first. I have edited the post. Just note that it wil return "0.0000" when value is undefined.
-
Jordan Arseno over 8 yearscaution:
toFixed()
returns a string. -
JohnnyBizzle over 7 yearsAnd what if you add 100? Do you need to change it to number.toPrecision(5)?
-
ReSpawN over 7 yearsYes. 31.939383.toPrecision(4) > "31.94" / 131.939383.toPrecision(4) > "131.9"
-
AaA over 6 years@Christoph, I believe it is happening because of stacking all vars and calculations with comma on a single var statement. It breaks the debugger, but works in browser.I had similar case with a larger script, if I remember correctly on Firefox 42
-
Stephen Romero over 5 years@JordanArseno this can be fixed using parseInt(myNumber.toFixed(intVar)); to return an integer value, or parseFloat(myNumber.toFixed(floatVar)); to return a float if user has decimal places.
-
George Birbilis over 4 yearsbtw, POSITS are promising for future h/w architectures: nextplatform.com/2019/07/08/…