How can I round a number in JavaScript? .toFixed() returns a string?
It returns a string because 0.1, and powers thereof (which are used to display decimal fractions), are not representable (at least not with full accuracy) in binary floating-point systems.
For example, 0.1 is really 0.1000000000000000055511151231257827021181583404541015625, and 0.01 is really 0.01000000000000000020816681711721685132943093776702880859375. (Thanks to BigDecimal
for proving my point. :-P)
Therefore (absent a decimal floating point or rational number type), outputting it as a string is the only way to get it trimmed to exactly the precision required for display.
JS- toFixed returns a string, but I need a number to 6 digits
function myFunction() {
var a = (1/2).toFixed(6) + "<br>"; var b = parseFloat(a).toFixed(6) + "<br>"; var x = new Decimal(123.4567) + "<br>"; var n = a + b + c; document.getElementById("demo").innerHTML = n; }
<script src="https://raw.githubusercontent.com/MikeMcl/decimal.js/master/decimal.min.js"></script>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
Formatting a number with exactly two decimals in JavaScript
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 round 90% of the time, it will return the rounded value, but for many cases, it doesn't work.
For instance:
2.005.toFixed(2) === "2.00"
UPDATE:
Nowadays, you can use the Intl.NumberFormat
constructor. It's part of the ECMAScript Internationalization API Specification (ECMA402). It has pretty good browser support, including even IE11, and it is fully supported in Node.js.
const formatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
console.log(formatter.format(2.005)); // "2.01"
console.log(formatter.format(1.345)); // "1.35"
Rounding in Javascript toFixed() method
As stated in the docs, toFixed()
does round when necessary. The rounding behavior is to round in the range -.5 < x <= +.5 of the digit.
The strange behavior you're observing is consistent with the note in the docs linked above:
Floating point numbers cannot represent all decimals precisely in binary which can lead to unexpected results such as 0.1 + 0.2 === 0.3 returning false .
In other words, this is a classic case of floating point precision loss - a problem you'll encounter in virtually any language. If you observe the full outputs of a
and b
you'll see that a == 0.075
and b == 0.07500000000000001
due to floating point precision - and thus given these values it is consistent with the defined rounding behavior to round a
to .07
and b
to .08
.
parseFloat(x).toFixe(2) returns a string
You can first add them and then achieve accuracy to 2 decimal points. The result will be more accurate.
function addDecimalStrings(decimalStringArr) {
let sum = 0;
for(let i=0; i<decimalStringArr.length; i++){
// Parse and add
sum = sum + parseFloat(decimalStringArr[i]);
}
// Convert to two decimal points
return sum.toFixed(2);
}
How to round to at most 2 decimal places, if necessary
Use Math.round()
:
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
How do you round to 1 decimal place in Javascript?
Math.round(num * 10) / 10
works, here is an example...
var number = 12.3456789
var rounded = Math.round(number * 10) / 10
// rounded is 12.3
if you want it to have one decimal place, even when that would be a 0, then add...
var fixed = rounded.toFixed(1)
// fixed is always to 1 d.p.
// NOTE: .toFixed() returns a string!
// To convert back to number format
parseFloat(number.toFixed(2))
// 12.34
// but that will not retain any trailing zeros
// So, just make sure it is the last step before output,
// and use a number format during calculations!
EDIT: Add round with precision function...
Using this principle, for reference, here is a handy little round function that takes precision...
function round(value, precision) {
var multiplier = Math.pow(10, precision || 0);
return Math.round(value * multiplier) / multiplier;
}
... usage ...
round(12345.6789, 2) // 12345.68
round(12345.6789, 1) // 12345.7
... defaults to round to nearest whole number (precision 0) ...
round(12345.6789) // 12346
... and can be used to round to nearest 10 or 100 etc...
round(12345.6789, -1) // 12350
round(12345.6789, -2) // 12300
... and correct handling of negative numbers ...
round(-123.45, 1) // -123.4
round(123.45, 1) // 123.5
... and can be combined with toFixed to format consistently as string ...
round(456.7, 2).toFixed(2) // "456.70"
What is the rule behind toFixed() function
About toFixed
Returns a String containing this Number value represented in decimal fixed-point notation with fractionDigits digits after the decimal point. If fractionDigits is undefined, 0 is assumed. Specifically, perform the following steps:
Algorithm Number.prototype.toFixed (fractionDigits)
: https://www.ecma-international.org/ecma-262/5.1/#sec-15.7.4.5
The length property of the toFixed method is 1.
- If the toFixed method is called with more than one argument, then the behaviour is undefined (see clause 15).
An implementation is permitted to extend the behaviour of toFixed for values of fractionDigits less than 0 or greater than 20. In this case toFixed would not necessarily throw RangeError for such values.
NOTE The output of toFixed may be more precise than toString for some values because toString only prints enough significant digits to distinguish the number from adjacent number values.
JS Work Around
function fix(n, p) { return (+(Math.round(+(n + 'e' + p)) + 'e' + -p)).toFixed(p);}let exampleA = fix(49.1175, 3);let exampleB = fix(49.1775, 3);let exampleC = fix(49.775, 2);const random = Math.random();console.log(exampleA);console.log(exampleB);console.log(exampleC);console.log('Before:', random, 'After Custom =>', fix(random, 3), 'Default:', random.toFixed(3));// 49.118// 49.178// 49.78
JavaScript: Round to a number of decimal places, but strip extra zeros
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0
Related Topics
How to Get the Global Object in JavaScript
How to Stop Babel from Transpiling 'This' to 'Undefined' (And Inserting "Use Strict")
(Deep) Copying an Array Using Jquery
JavaScript to Sort Contents of Select Element
Es6 Promise.All() Error Handle - Is .Settle() Needed
Facebook How to Check If User Has Liked Page and Show Content
Rendering React Components from Array of Objects
Multiple Path Names for a Same Component in React Router
How to Sort an Array of Objects Based on the Ordering of Another Array
Convert Object Array to Hash Map, Indexed by an Attribute Value of the Object
Reactjs Setstate() with a Dynamic Key Name
How to Replace Captured Groups Only
Retrieving Binary File Content Using JavaScript, Base64 Encode It and Reverse-Decode It Using Python
How Is JavaScript Single Threaded
Understanding Ajax Cors and Security Considerations
How to Trigger a Link's (Or Any Element'S) Click Event Through JavaScript