I would like to format my numbers to always display 2 decimal places, rounding where applicable.
Examples:
number display
------ -------
1 1.00
1.341 1.34
1.345 1.35
I have been using this:
parseFloat(num).toFixed(2);
But it's displaying 1
as 1
, rather than 1.00
.
(Math.round(num * 100) / 100).toFixed(2);
Live Demo
var num1 = "1"; document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2); var num2 = "1.341"; document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2); var num3 = "1.345"; document.getElementById('num3').innerHTML = (Math.round(num3 * 100) / 100).toFixed(2); span { border: 1px solid #000; margin: 5px; padding: 5px; }
Note that it will round to 2 decimal places, so the input 1.346
will return 1.35
.
Number(1).toFixed(2); // 1.00
Number(1.341).toFixed(2); // 1.34
Number(1.345).toFixed(2); // 1.34 NOTE: See andy's comment below.
Number(1.3450001).toFixed(2); // 1.35
document.getElementById('line1').innerHTML = Number(1).toFixed(2);
document.getElementById('line2').innerHTML = Number(1.341).toFixed(2);
document.getElementById('line3').innerHTML = Number(1.345).toFixed(2);
document.getElementById('line4').innerHTML = Number(1.3450001).toFixed(2);
1.34
for expression Number(1.345).toFixed(2)
.
1.345
is an example of a number that can't be stored exactly in floating point, so I think the reason that it doesn't round as you expect, is that it's actually stored as a number slightly less than 1.345 and it rounds down. If you test instead with (1.34500001).toFixed(2)
then you see it correctly rounds up to 1.35
This answer will fail if value = 1.005
.
As a better solution, the rounding problem can be avoided by using numbers represented in exponential notation:
Number(Math.round(1.005+'e2')+'e-2'); // 1.01
Cleaner code as suggested by @Kon, and the original author:
Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)
You may add toFixed()
at the end to retain the decimal point e.g: 1.00
but note that it will return as string.
Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces).toFixed(decimalPlaces)
Credit: Rounding Decimals in JavaScript
toFixed
has that rounding problem. Your answer should be the accepted one.
Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)
For modern browsers, use toLocaleString
:
var num = 1.345;
num.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 });
Specify a locale tag as first parameter to control the decimal separator. For a dot, use for example English U.S. locale:
num.toLocaleString("en-US", { maximumFractionDigits: 2, minimumFractionDigits: 2 });
which gives:
1.35
Most countries in Europe use a comma as decimal separator, so if you for example use Swedish/Sweden locale:
num.toLocaleString("sv-SE", { maximumFractionDigits: 2, minimumFractionDigits: 2 });
it will give:
1,35
var num = new Number(14.12); console.log(num.toPrecision(2)); //outputs 14 console.log(num.toPrecision(3)); //outputs 14.1 console.log(num.toPrecision(4)); //outputs 14.12 console.log(num.toPrecision(5)); //outputs 14.120
toPrecision
only formats the number to a specific number of decimal places, simply leaving out redundant places, but not rounding them. This could be very useful too of course, but it's important to understand the difference.
(20.55).toPrecision(3) "20.6"
toFixed
: const formattedVal = Number(val.toFixed(2));
Do not use toPrecision
, as it counts the non-decimal numbers when using the precision param.
I would suggest you use
new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(num)
that way you will also have the local format of a country you specify, plus it would garantee to show exact 2 decimals (whether when num is 1 or 1.12345, it will show 1.00 and 1.12 respectively)
In this example I used German localization, because I wanted my numbers show with thousands delimiter, so this would be some outputs:
1 => 1,00
1.12 => 1,12
1.1234 => 1,12
1234 => 1.234,00
1234.1234 => 1.234,12
For the most accurate rounding, create this function and use it to round to 2 decimal places:
function round(value, decimals) { return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals).toFixed(decimals); } console.log("seeked to " + round(1.005, 2));
> 1.01
Thanks to Razu, this article, and MDN's Math.round reference.
Simplest answer:
var num = 1.2353453;
num.toFixed(2); // 1.24
Example: http://jsfiddle.net/E2XU7/
toFixed
was already suggested in stackoverflow.com/a/13292833/218196. What additional information does your question provide?
toFixed
on a number.
A much more generic solution for rounding to N places
function roundN(num,n){
return parseFloat(Math.round(num * Math.pow(10, n)) /Math.pow(10,n)).toFixed(n);
}
console.log(roundN(1,2))
console.log(roundN(1.34,2))
console.log(roundN(1.35,2))
console.log(roundN(1.344,2))
console.log(roundN(1.345,2))
console.log(roundN(1.344,3))
console.log(roundN(1.345,3))
console.log(roundN(1.3444,3))
console.log(roundN(1.3455,3))
Output
1.00
1.34
1.35
1.34
1.35
1.344
1.345
1.344
1.346
roundN(-3.4028230607370965e+38,2)
returns "-3.4028230607370965e+38"
instead of the expected 0.00
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat
var number = 123456.789; console.log(new Intl.NumberFormat('en-IN', { maximumFractionDigits: 2 }).format(number));
If you're already using jQuery, you could look at using the jQuery Number Format plugin.
The plugin can return formatted numbers as a string, you can set decimal, and thousands separators, and you can choose the number of decimals to show.
$.number( 123, 2 ); // Returns '123.00'
You can also get jQuery Number Format from GitHub.
You are not giving us the whole picture.
javascript:alert(parseFloat(1).toFixed(2))
shows 1.00 in my browsers when I paste it into the location bar. However if you do something to it afterwards, it will revert.
alert(parseFloat(1).toFixed(2)) var num = 2 document.getElementById('spanId').innerHTML = (parseFloat(num).toFixed(2) - 1)
shows 1 and not 1.00
Is this what you mean?
[edit 20200530] The answer @razu provided is the best imho. So here's a slightly refactored version.
The snippet code will still not return the right value for something like showAsFloat(2.3346)
(result 2.33, but should be 2.34). So, see also.
const showAsFloat = (input, decimals = 2, asString = false) => { if (input === null || input.constructor === Boolean || isNaN(+input)) { return input; } const converted = +( `${Math.round( parseFloat( `${input}e${decimals}` ) )}e-${decimals}` ); return asString ? converted.toFixed(decimals) : converted }; document.querySelector('#result').textContent = [ 'command | result', '-----------------------------------------------', 'showAsFloat(1); | ' + showAsFloat(1), 'showAsFloat(1.314); | ' + showAsFloat(1.314), 'showAsFloat(\'notanumber\') | ' + showAsFloat('notanumber'), 'showAsFloat(\'23.44567\', 3) | ' + showAsFloat('23.44567', 3), 'showAsFloat(2456198, 5, true)| ' + showAsFloat('24568', 5, true), 'showAsFloat(2456198, 5) | ' + showAsFloat('24568', 5), 'showAsFloat(0, 2, true); | ' + showAsFloat(0, 2, true), 'showAsFloat(1.345); | ' + showAsFloat(1.345), 'showAsFloat(0.005); | ' + showAsFloat(0.005), 'showAsFloat(null); | ' + showAsFloat(null), ].join('\n');
1.005
comes out to 1.00
, and 1.345
as 1.34
.
Are you looking for floor?
var num = 1.42482; var num2 = 1; var fnum = Math.floor(num).toFixed(2); var fnum2 = Math.floor(num2).toFixed(2); console.log(fnum + " and " + fnum2); //both values will be 1.00
Convert a number into a string, keeping only two decimals:
var num = 5.56789;
var n = num.toFixed(2);
The result of n will be:
5.57
Just run into this one of longest thread, below is my solution:
parseFloat(Math.round((parseFloat(num * 100)).toFixed(2)) / 100 ).toFixed(2)
Let me know if anyone can poke a hole
function currencyFormat (num) {
return "$" + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}
console.info(currencyFormat(2665)); // $2,665.00
console.info(currencyFormat(102665)); // $102,665.00
Here's also a generic function that can format to any number of decimal places:
function numberFormat(val, decimalPlaces) {
var multiplier = Math.pow(10, decimalPlaces);
return (Math.round(val * multiplier) / multiplier).toFixed(decimalPlaces);
}
Where specific formatting is required, you should write your own routine or use a library function that does what you need. The basic ECMAScript functionality is usually insufficient for displaying formatted numbers.
A thorough explanation of rounding and formatting is here:
http://www.merlyn.demon.co.uk/js-round.htm#RiJ
As a general rule, rounding and formatting should only be peformed as a last step before output. Doing so earlier may introduce unexpectedly large errors and destroy the formatting.
here is another solution to round only using floor, meaning, making sure calculated amount won't be bigger than the original amount (sometimes needed for transactions):
Math.floor(num* 100 )/100;
function number_format(string,decimals=2,decimal=',',thousands='.',pre='R$ ',pos=' Reais'){ var numbers = string.toString().match(/\d+/g).join([]); numbers = numbers.padStart(decimals+1, "0"); var splitNumbers = numbers.split("").reverse(); var mask = ''; splitNumbers.forEach(function(d,i){ if (i == decimals) { mask = decimal + mask; } if (i>(decimals+1) && ((i-2)%(decimals+1))==0) { mask = thousands + mask; } mask = d + mask; }); return pre + mask + pos; } var element = document.getElementById("format"); var money= number_format("10987654321",2,',','.'); element.innerHTML = money; #format{ display:inline-block; padding:10px; border:1px solid #ddd; background:#f5f5f5; }
Try below code:
function numberWithCommas(number) {
var newval = parseFloat(Math.round(number * 100) / 100).toFixed(2);
return newval.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
var quantity = 12;
var import1 = 12.55;
var total = quantity * import1;
var answer = parseFloat(total).toFixed(2);
document.write(answer);
I had to decide between the parseFloat() and Number() conversions before I could make toFixed() call. Here's an example of a number formatting post-capturing user input.
HTML:
<input type="number" class="dec-number" min="0" step="0.01" />
Event handler:
$('.dec-number').on('change', function () {
const value = $(this).val();
$(this).val(value.toFixed(2));
});
The above code will result in TypeError exception. Note that although the html input type is "number", the user input is actually a "string" data type. However, toFixed() function may only be invoked on an object that is a Number.
My final code would look as follows:
$('.dec-number').on('change', function () {
const value = Number($(this).val());
$(this).val(value.toFixed(2));
});
The reason I favor to cast with Number() vs. parseFloat() is because I don't have to perform an extra validation neither for an empty input string, nor NaN value. The Number() function would automatically handle an empty string and covert it to zero.
var num1 = "0.1"; document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2); var num2 = "1.341"; document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2); var num3 = "1.345"; document.getElementById('num3').innerHTML = (Math.round(num3 * 100) / 100).toFixed(2); span { border: 1px solid #000; margin: 5px; padding: 5px; }
parseFloat(num.toFixed(2))
RegExp - alternative approach
On input you have string (because you use parse) so we can get result by using only string manipulations and integer number calculations
let toFix2 = (n) => n.replace(/(-?)(\d+)\.(\d\d)(\d+)/, (_,s,i,d,r)=> { let k= (+r[0]>=5)+ +d - (r==5 && s=='-'); return s + (+i+(k>99)) + "." + ((k>99)?"00":(k>9?k:"0"+k)); }) // TESTs console.log(toFix2("1")); console.log(toFix2("1.341")); console.log(toFix2("1.345")); console.log(toFix2("1.005"));
Explanation
s is sign, i is integer part, d are first two digits after dot, r are other digits (we use r[0] value to calc rounding)
k contains information about last two digits (represented as integer number)
if r[0] is >=5 then we add 1 to d - but in case when we have minus number (s=='-') and r is exact equal to 5 then in this case we substract 1 (for compatibility reasons - in same way Math.round works for minus numbers e.g Math.round(-1.5)==-1)
after that if last two digits k are greater than 99 then we add one to integer part i
I do like:
var num = 12.749;
parseFloat((Math.round(num * 100) / 100).toFixed(2)); // 123.75
Round the number with 2 decimal points, then make sure to parse it with parseFloat()
to return Number, not String unless you don't care if it is String or Number.
parseFloat("1.00") // 1
Extend Math object with precision method
Object.defineProperty(Math, 'precision',{ value: function (value,precision,type){ var v = parseFloat(value), p = Math.max(precision,0)||0, t = type||'round'; return (Math[t](v*Math.pow(10,p))/Math.pow(10,p)).toFixed(p); } }); console.log( Math.precision(3.1,3), // round 3 digits Math.precision(0.12345,2,'ceil'), // ceil 2 digits Math.precision(1.1) // integer part )
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js" integrity="sha512-pHVGpX7F/27yZ0ISY+VVjyULApbDlD0/X0rgGbTqCE7WFW5MezNTWG/dnhtbBuICzsd0WQPgpE4REBLv+UqChw==" crossorigin="anonymous"></script>
<input type="text" class = 'item_price' name="price" min="1.00" placeholder="Enter Price" value="{{ old('price') }}" step="">
<script>
$(document).ready(function() {
$('.item_price').mask('00000.00', { reverse: true });
});
</script>
Success story sharing
1
to display as1.00
, and1.341
to display as1.34
.(+num).toFixed(2)
. It even retains the rounding bug in the original, see Nate's answer.