How to format numbers as currency strings
Solution 1
Ok, based on what you said, I'm using this:
var DecimalSeparator = Number("1.2").toLocaleString().substr(1,1);
var AmountWithCommas = Amount.toLocaleString();
var arParts = String(AmountWithCommas).split(DecimalSeparator);
var intPart = arParts[0];
var decPart = (arParts.length > 1 ? arParts[1] : '');
decPart = (decPart + '00').substr(0,2);
return '£ ' + intPart + DecimalSeparator + decPart;
I'm open to improvement suggestions (I'd prefer not to include YUI just to do this :-) )
I already know I should be detecting the "." instead of just using it as the decimal separator...
Solution 2
Intl.NumberFormat
JavaScript has a number formatter (part of the Internationalization API).
// Create our number formatter.
var formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
// These options are needed to round to whole numbers if that's what you want.
//minimumFractionDigits: 0, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)
//maximumFractionDigits: 0, // (causes 2500.99 to be printed as $2,501)
});
formatter.format(2500); /* $2,500.00 */
Use undefined
in place of the first argument ('en-US'
in the example) to use the system locale (the user locale in case the code is running in a browser). Further explanation of the locale code.
Here's a list of the currency codes.
Intl.NumberFormat vs Number.prototype.toLocaleString
A final note comparing this to the older .toLocaleString
. They both offer essentially the same functionality. However, toLocaleString in its older incarnations (pre-Intl) does not actually support locales: it uses the system locale. So when debugging old browsers, be sure that you're using the correct version (MDN suggests to check for the existence of Intl
). There isn't any need to worry about this at all if you don't care about old browsers or just use the shim.
Also, the performance of both is the same for a single item, but if you have a lot of numbers to format, using Intl.NumberFormat
is ~70 times faster. Therefore, it's usually best to use Intl.NumberFormat
and instantiate only once per page load. Anyway, here's the equivalent usage of toLocaleString
:
(2500).toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
}); /* $2,500.00 */
Some notes on browser support and Node.js
- Browser support is no longer an issue nowadays with 98% support globally, 99% in the US and 99+% in the EU
- There is a shim to support it on fossilized browsers (like Internet Explorer 8), should you really need to
- Node.js before v13 only supports
en-US
out of the box. One solution is to install full-icu, see here for more information - Have a look at CanIUse for more information
Solution 3
Number.prototype.toFixed
This solution is compatible with every single major browser:
const profits = 2489.8237;
profits.toFixed(3) // Returns 2489.824 (rounds up)
profits.toFixed(2) // Returns 2489.82
profits.toFixed(7) // Returns 2489.8237000 (pads the decimals)
All you need is to add the currency symbol (e.g. "$" + profits.toFixed(2)
) and you will have your amount in dollars.
Custom function
If you require the use of ,
between each digit, you can use this function:
function formatMoney(number, decPlaces, decSep, thouSep) {
decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces,
decSep = typeof decSep === "undefined" ? "." : decSep;
thouSep = typeof thouSep === "undefined" ? "," : thouSep;
var sign = number < 0 ? "-" : "";
var i = String(parseInt(number = Math.abs(Number(number) || 0).toFixed(decPlaces)));
var j = (j = i.length) > 3 ? j % 3 : 0;
return sign +
(j ? i.substr(0, j) + thouSep : "") +
i.substr(j).replace(/(\decSep{3})(?=\decSep)/g, "$1" + thouSep) +
(decPlaces ? decSep + Math.abs(number - i).toFixed(decPlaces).slice(2) : "");
}
document.getElementById("b").addEventListener("click", event => {
document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>
Use it like so:
(123456789.12345).formatMoney(2, ".", ",");
If you're always going to use '.' and ',', you can leave them off your method call, and the method will default them for you.
(123456789.12345).formatMoney(2);
If your culture has the two symbols flipped (i.e., Europeans) and you would like to use the defaults, just paste over the following two lines in the formatMoney
method:
d = d == undefined ? "," : d,
t = t == undefined ? "." : t,
Custom function (ES6)
If you can use modern ECMAScript syntax (i.e., through Babel), you can use this simpler function instead:
function formatMoney(amount, decimalCount = 2, decimal = ".", thousands = ",") {
try {
decimalCount = Math.abs(decimalCount);
decimalCount = isNaN(decimalCount) ? 2 : decimalCount;
const negativeSign = amount < 0 ? "-" : "";
let i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString();
let j = (i.length > 3) ? i.length % 3 : 0;
return
negativeSign +
(j ? i.substr(0, j) + thousands : '') +
i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) +
(decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : "");
} catch (e) {
console.log(e)
}
};
document.getElementById("b").addEventListener("click", event => {
document.getElementById("x").innerText = "Result was: " + formatMoney(document.getElementById("d").value);
});
<label>Insert your amount: <input id="d" type="text" placeholder="Cash amount" /></label>
<br />
<button id="b">Get Output</button>
<p id="x">(press button to get output)</p>
Solution 4
Short and fast solution (works everywhere!)
(12345.67).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,'); // 12,345.67
The idea behind this solution is replacing matched sections with first match and comma, i.e. '$&,'
. The matching is done using lookahead approach. You may read the expression as "match a number if it is followed by a sequence of three number sets (one or more) and a dot".
TESTS:
1 --> "1.00"
12 --> "12.00"
123 --> "123.00"
1234 --> "1,234.00"
12345 --> "12,345.00"
123456 --> "123,456.00"
1234567 --> "1,234,567.00"
12345.67 --> "12,345.67"
DEMO: http://jsfiddle.net/hAfMM/9571/
Extended short solution
You can also extend the prototype of Number
object to add additional support of any number of decimals [0 .. n]
and the size of number groups [0 .. x]
:
/**
* Number.prototype.format(n, x)
*
* @param integer n: length of decimal
* @param integer x: length of sections
*/
Number.prototype.format = function(n, x) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\.' : '$') + ')';
return this.toFixed(Math.max(0, ~~n)).replace(new RegExp(re, 'g'), '$&,');
};
1234..format(); // "1,234"
12345..format(2); // "12,345.00"
123456.7.format(3, 2); // "12,34,56.700"
123456.789.format(2, 4); // "12,3456.79"
DEMO / TESTS: http://jsfiddle.net/hAfMM/435/
Super extended short solution
In this super extended version you may set different delimiter types:
/**
* Number.prototype.format(n, x, s, c)
*
* @param integer n: length of decimal
* @param integer x: length of whole part
* @param mixed s: sections delimiter
* @param mixed c: decimal delimiter
*/
Number.prototype.format = function(n, x, s, c) {
var re = '\\d(?=(\\d{' + (x || 3) + '})+' + (n > 0 ? '\\D' : '$') + ')',
num = this.toFixed(Math.max(0, ~~n));
return (c ? num.replace('.', c) : num).replace(new RegExp(re, 'g'), '$&' + (s || ','));
};
12345678.9.format(2, 3, '.', ','); // "12.345.678,90"
123456.789.format(4, 4, ' ', ':'); // "12 3456:7890"
12345678.9.format(0, 3, '-'); // "12-345-679"
DEMO / TESTS: http://jsfiddle.net/hAfMM/612/
Solution 5
Take a look at the JavaScript Number object and see if it can help you.
-
toLocaleString()
will format a number using location specific thousands separator. -
toFixed()
will round the number to a specific number of decimal places.
To use these at the same time the value must have its type changed back to a number because they both output a string.
Example:
Number((someNumber).toFixed(1)).toLocaleString()
EDIT
One can just use toLocaleString directly and its not necessary to recast to a number:
someNumber.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2});
Multiple numbers
If you need to frequently format numbers similarly you can create a specific object for reuse. Like for German (Switzerland):
const money = new Intl.NumberFormat('de-CH',
{ style:'currency', currency: 'CHF' });
const percent = new Intl.NumberFormat('de-CH',
{ style:'percent', maximumFractionDigits: 1, signDisplay: "always"});
which than can be used as:
money.format(1234.50); // output CHF 1'234.50
percent.format(0.083); // output +8.3%
Pretty nifty.
recursive9
Founder of Crystal Gears Portfolio: - www.movertrends.com - www.friendshopper.com - www.digitalshow.com - www.translatorscorner.com - www.gigpay.com
Updated on July 08, 2022Comments
-
recursive9 almost 2 years
I would like to format a price in JavaScript. I'd like a function which takes a
float
as an argument and returns astring
formatted like this:"$ 2,500.00"
What's the best way to do this?
-
recursive9 over 15 yearsPreferably, not necessarily. I just posted an answer that does, I think, based of people's suggestions
-
Philip Whitehouse about 12 yearsPlease, to anyone reading this in the future, do not use float to store currency. You will loose precision and data. You should store it as a integer number of cents (or pennies etc.) and then convert prior to output.
-
Kyle almost 12 years@PhilipWhitehouse what would cause loss of data of less than 2 decimal places?
-
Philip Whitehouse almost 12 years@user1308743 Float doesn't store decimal places. It stores numbers using a value, base and offset. 0.01 is not actually representable. See: en.wikipedia.org/wiki/Floating_point#Accuracy_problems
-
ereOn almost 12 years@user1308743: Imagine you represent a very big number (lets say you are a lucky guy and it is your bank account balance). Would you really want to loose money because of a precision deficiency ?
-
Ben Hull about 11 years@PhilipWhitehouse is right: it's definitely a bad idea to store money as floats. However, storing money as cents only works when you're dealing only in whole cents, which isn't precise enough for a lot of operations. We've recently switched to storing currencies as a 'Big Decimal', of 7 decimal places. You can use Javascript's toFixed(7) method to emulate this, though it returns a string by necessity. It does mean you can deal in familiar $xx.xx formats, though, without converting back from cents.
-
Nick Grealy over 10 yearsSo why hasn't anyone suggested the following? (2500).toLocaleString("en-GB", {style: "currency", currency: "GBP", minimumFractionDigits: 2}) developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
Ben over 9 years@NickG I am guessing because of it's pretty rubbish support from legacy browsers. But in an ideal world (where everyone has up to date browsers) this would be the best solution.
-
Aarthi Chandrasekaran over 9 yearsyou can use this Numeral.js javascript library to convert your numbers to dollars. (numeraljs.com) for reference.
-
einstein over 9 yearsDon't forget the English language wrap negative currency amounts in parentthesis
($#,##0.00)
. -
Testo Testini over 9 years@NickG I was enthusiast of your solution but does not work in IPad, Android and IE7, works only in Mozilla and Opera of what I checked
-
Nick Grealy over 9 years@TestoTestini - thanks, fyi Mozilla have documented a compatibility table for browsers developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
-
cssyphus over 9 years@TestoTestini (a)NickG See this jsFiddle: jsfiddle.net/v7tws309
-
Bergi about 9 years@RoccoTheTaco: Not sure what you're saying. The other question is older, has more upvotes, more answers, and a higher-voted answer. The (subjective) avg quality of the answers is similar. To be honest though, they best should be merged.
-
Bergi about 9 yearsThere's nothing wrong with being generic, is it?
-
Curtis Yallop almost 9 years@PhilipWhitehouse While it is not good to store it as float, I believe it is ok to display currency in js as floats. As long as you don't perform calculations on it eg sum a column, etc. I store and manipulate the value in c# decimal and simply send it down to js as a float where it is displayed. If you type ".1" or ".61" into the console, it displays fine even though "1.03-.42" does not. Rudimentary test: for(var i = -200; i <= 200; ++i) console.log(i/100); I also send edited floats back up to my web server which should be ok: JSON.stringify(.1): "0.1".
-
Amir about 7 yearsIf you're reading this in >= 2017, this should be useful: link
-
aross almost 7 years@Amir, that's already in my answer
-
LogicDaemon about 5 years@CurtisYallop only if showing value without currency, because english.stackexchange.com/a/11327/118419
-
Mike Aron over 3 years@NickGrealy Holy shittt. Dude i did not know this function. I wrote always my custom functions. Cooooool. THX
-
Nick Grealy over 3 yearsThanks @MikeAron, anytime. Give this a +1 to help others - stackoverflow.com/a/18994850/782034
-
Rajeev Jayaswal over 3 yearsFor INR conversion - use (4027775861.4).toLocaleString('en-IN', { maximumFractionDigits: 2, style: 'currency', currency: 'INR' }); // returns -> "₹4,02,77,75,861.40"
-
Peter Mortensen about 3 years@Philip Whitehouse: *lose precision (not loose precision). (Only a moderator can fix it - it is possible to raise a moderator flag.)
-
-
recursive9 over 15 yearsToo long, and i'd have to include YUI
-
recursive9 over 15 yearsThanks! Based on this idea I was able to make one that is short and simple enough! (and localized) Excellent.
-
recursive9 over 15 yearsSorry, no. That will remove extra decimal places, but it won't fix to 2 decimal positions. "25" will be "$ 25" with your code, not "$ 25.00"
-
Ates Goral over 15 yearsNote that your version doesn't properly round to two decimal digits. For example, 3.706 would be formatted as "£ 3.70", not as "£ 3.71" as it's supposed to be.
-
recursive9 over 15 yearsYes, that's OK in my particular case, since the amounts I'm working with already have at most 2 digits The reason I need to fix to 2 decimals is for amounts with no decimals or with only 1.
-
recursive9 over 15 yearsStill wrong! You're using toLocaleString, which can make the decimal separator "," instead of ".", and assuming it's "."
-
Ates Goral over 15 yearsThis was a "minimalistic" approach to meet the original vague requirements that just gave "$ 2,500.00" as an example.
-
Ryan over 13 yearsIf you always want to round up on 5 and down below 5, you cannot rely on toFixed() because of standard issues involved in representing floating point in binary. For example, try
(1.005).toFixed(2)
. -
Ricardo Gomes over 13 yearsfirst of all, excellent, concise code. however, if you are american, you should change the defaults of
d
andt
to be.
and,
respectively so that you don't have to specify them every time. also, i recommend modifying the beginning of thereturn
statement to read:return s + '$' + [rest]
, otherwise you will not get a dollar sign. -
Zhenya over 12 yearsThanks, this is great. Modified to work with user input strings instead (strips the string to numerics first in case they enter $1,500). String.prototype.formatMoney = function(c, d, t){ var n_dirty = this, n = n_dirty.replace(/[^\d.]/g,''), c = isNaN(c = Math.abs(c)) ? 2 : c, d = d == undefined ? "." : d, t = t == undefined ? "," : t, s = n < 0 ? "-" : "", i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 : 0; return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); };
-
vector over 12 years... just remember to pass a currency symbol otherwise it errors out in IE7 and IE8, IE9 is fine either way
-
sohtimsso1970 over 12 yearsYou may want to use '10' as the radix in parseInt. Otherwise, any number that starts with '0' will use octal numbering.
-
sohtimsso1970 over 12 yearsYou may want to use '10' as the radix in parseInt. Otherwise, any number that starts with '0' will use octal numbering.
-
Patrick Desjardins over 12 yearsThe default value of 0 to be octal is still there but deprecated. But yes you can add it if you want.
-
Nick Perkins over 12 yearsMy first reaction was "lol--too long, YUI sucks"...but upon reconsideration, it's not bad code, it's just very...complete. It checks whether the arg is actually a number ( not done by other posters, and the only part that requires YUI library ). It does rounding ( not done by all posters ). It has configurable separator, prefix, and suffix. Lastly, the code is commented, and uses no regex and no tricky one-liners. So...I am giving you a +1 to compensate for others -1...this code is not bad -- it could be adapted even if not using YUI.
-
Steve over 12 yearspoetry. brilliant. have you tried reduceRight() developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… which should eliminate the reverse() ?
-
Wayne over 12 years@Steve - You're right, but you'd need to do something like
i = orig.length - i - 1
in the callback. Still, one less traversal of the array. -
Mat Schaffer over 12 yearsLooks like the IE7/IE8 bug is fixed.
-
Marco Demaio over 12 yearsAt YUI they must be sick, can't believe they wrote such piece of code.
-
Marco Demaio over 12 years@sohtimsso1970: sorry for the late response, but could you explain some more? I don't see where a number could be interpreted as octal. The
parseInt
is called on the absolute value of the INTEGER part of the number. The INTEGER part can not start with ZERO unless it's just a ZERO! AndparseInt(0) === 0
either octal or decimal. -
Rocco The Taco over 12 years@ crush this works but it no longer carries the calculations onto the tax field?
-
crush over 12 yearsOnce you append a $ sign to it, it is no longer a number, but a string.
-
Tracker1 about 12 yearstry, for example: parseInt("016") ... returns 14, as parseInt assumes it's octal encoded, when the string begins with a zero.
-
Marco Demaio about 12 years@Tracker1: I understood that a number starting with
0
is considered octal byparseInt
. But in this code is IMPOSSIBLE forparseInt
to receive016
as input (or any other octal formatted value), because the argument passed toparseInt
is 1st processed byMath.abs
function. So there is no way forparseInt
to receive a number that starts with zero unless it's just a zero or0.nn
(wherenn
are decimals). But both0
and0.nn
strings would be converted byparseInt
into a plain ZERO as suppsed to be. -
Blaise about 12 yearsA not about compatability: The
reduce
method was introduced in Ecmascript 1.8, and is not supported in Internet Explorer 8 and below. -
Ian Dunn over 11 yearsThis answer looks redundant. Crush's answer already mentinoed
toFixed()
-
farinspace over 11 yearsThis is a great library, being able to pass the currency symbol is also a good idea, since all the currency details are contained in the single function call/settings
-
usr over 11 yearsNot sure why people think this code is beautiful. It is indecipherable. It seems to work nicely, but it is not beautiful.
-
jao over 11 yearsplease provide an example on how to use the function.
-
timborden over 11 years
toFixed()
is a function of theNumber
object and won't work onvar num
if it was aString
, so the additional context helped me. -
zuallauz over 11 yearsIs this formatMoney function copied from some minified JavaScript code somewhere? Can you not post the original? What do the variables c, d, i, j, n, s, and t stand for? Judging by the amount of upvotes and comments this post has I can assume this code has been copy pasted into production websites everywhere... Good luck maintaining the code if it has a bug some day!
-
Nick Colgan over 11 yearsThis solution doesn't work very well. 1.155.formatMoney(2,'.',',) === '1.16', but 2.155.formatMoney(2,'.',',') === '2.15'
-
keithjgrant over 11 years"poetry"? More like obscurity. This isn't code golf; use a little white space. Proper var names wouldn't hurt, either.
-
kalisjoshua about 11 yearsI actually went a step further:
.replace(/(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,")
. -
Rich Bradshaw about 11 yearsThe first var is kinda weird, as those variables are already declared in the function declaration. Other than that, thanks!
-
Eric Anderson almost 11 yearsCoffeeScript version with of VisioN & kalisjoshua regexp and way of specifying decimal place (so you can leave the default of 2 or specify 0 for no decimal):
Number.prototype.toMoney = (decimal=2) -> @toFixed(decimal).replace /(\d)(?=(\d{3})+(?:\.\d+)?$)/g, "$1,"
-
rsbarro almost 11 yearsLike @Blaise said, this method will not work in IE 8 or below.
-
Abbas almost 11 yearsIf we call toFixed(0), the commas disappear, any idea on getting it to work with
this.toFixed(0).replace(/(\d)(?=(\d{3})+\.)/g, "$1,")
? -
Joseph Lennox almost 11 yearsThe point of toLocaleString is that it does adjust with the user's settings.
-
VisioN almost 11 years@Abbas Yeah, replace
\.
with$
(end of line), i.e.this.toFixed(0).replace(/(\d)(?=(\d{3})+$)/g, "$1,")
. -
trejder over 10 yearsNot mentioning, that
d == undefined
is used, whiletypeof(d) === 'undefined'
should be in place. -
pbarranis over 10 yearsWow, why is this not upvoted more? Big standardized library for all sorts of formatting. Industry-standard formatting parameters with correct globalization. Great answer!!
-
Wayne over 10 yearsYes, that's of course correct. As noted in the answer itself, this is just for fun. Also, it should handle negative numbers just fine.
-
VisioN over 10 yearsBecause 'locales' and 'options' arguments are supported just by a very small number of browsers, like Chrome 24, IE11 and Opera 15. Firefox, Safari and older versions of others still don't support it.
-
Micaël Félix over 10 years@trejder why so? If you have silly programmers that define undefined as a variable with content you're good to go. Btw you don't need to (and so should not) use parenthesis for typeof.
-
trejder over 10 years@MykaEyl Read about JS fundamentals before you say things, that are... a little bit wrong. A variable named
undefined
is defined by JS, not by some silly programmers and you should use parenthesis fortypeof
, because without it you'll be comparing it to that variable, namedundefined
. I don't present here my own thoughts, I just copied what is expressed in many SO answers and in many sources. Don't have time to find example right now, but you'll for sure find it, if you google a little bit more. -
Nick Grealy over 10 yearsAgreed, it's not fully supported across all browsers (yet), but it's still a solution. (And arguably the most valid solution, as its forward compatible with the non-supported browsers, and it's a documented feature of the Javascript api.)
-
XML over 10 yearsYou're right. That's an error I brought in from Jonathan M's original, where they're all chained as a single var expression. Those should be simple assignments. Fixing.
-
XML over 10 yearsFor that matter, I think this is probably prematurely optimized and should be refactored for readability. But my goal was to augment the OP's code, not fundamentally alter it.
-
Rich Bradshaw over 10 yearsIt's not too bad – the
+n || 0
is the only thing that seems a little odd (to me anyway). -
XML over 10 years
this
is a perfectly useful variable name. Converting it ton
so you can save 3 characters at definition time may have been necessary in an era when RAM and bandwidth were counted in KB, but is merely obfuscatory in an era when the minifier will take care of all that before it ever hits production. The other clever micro-optimizations are at least debatable. -
Rich Bradshaw over 10 yearsTrue – didn't catch that one.
-
hanumant over 10 yearsHi @VisioN, can you please explain the regex and importance of "$1,". I used the regex function but missed the $ in "$1,". So the result was incorrect. Will help me if you can explain. TIA.
-
VisioN over 10 years@hanumant The regular grammar is a bit complicated here, so I suggest you to read the manuals about regular expressions first (e.g. at MDN). The idea behind it is replacing matched sections with first match and comma, i.e.
$1,
. The matching is done using lookahead approach. You may read the expression as "match a number if it is followed by a sequence of three number sets (one or more) and a dot". -
Zaptree over 10 yearsActually You can. i.e. for dollars: '$'+(value + 0.001).toLocaleString().slice(0,-1)
-
user2864740 over 10 years@trejder The parenthesis with the typeof make absolutely no difference to how the construct is parsed that form -
typeof
has the same precedence as a unary operator. Also the previous comment was saying that it's safe to rely thatundefined
evaluates to(void 0)
as long as a "silly programmer" doesn't introduce a shadowingundefined
local variable or rebindwindow.undefined
. (I would consider that code the offender, not the code usingundefined
.) -
trejder over 10 years@user2864740 On second thought, I agree (of course!) on not using parenthesis (I had to be blind, when first time reading Myka Eyl's comment! :]). But I disagree on second part. The reason, why you should use
typeof d === 'undefined'
instead ofd === undefined
is, that with first approach you don't have to care about silly developers. Since world is overwhelmed by silly developers, we need to spend our time on actual coding, not of foreseeing silly developers' possible attempts to ruin our code, right? :] -
user2864740 over 10 years@trejder I've never run into that problem. Any environment in which
undefined
has been redefined to a value other than(void 0)
is an environment which I will not support. (In Python 2.x, True and False were just variables - e.g.True,False=False,True
is permissible - but there was never any push to find a "safe" method.) -
Luke Page over 10 yearsthis is just copied from a google search. The project hasn't been updated since 2011
-
hacklikecrack over 10 yearswatch out for globals sign, i, j
-
Jonathan M over 10 years@hacklikecrack, all variables are local; they're in the
var
statement. -
acorncom over 10 yearsLooks like it'd be great, but there is little browser support at the moment
-
Bob over 10 years@trejder Since world is overwhelmed by silly developers, we need to spend our time on actual coding, not of foreseeing silly developers' possible attempts to ruin our code, right? => Following that line of thought, isn't
typeof(d) === 'undefined'
an attempt at foreseeing silly developers' possible attempts to ruin our code? If someone actually redefinedundefined
, I wouldn't trust them not to do something else to break your code. -
hacklikecrack about 10 yearssorry, yes, though you're redeclaring arguments. Indentation! ;)
-
Michel Ayres about 10 years@VisioN in the case of values for Brazilian standards (R$ 1.222.333,44) receiving (122233344). How should be done? I tried some changes in the fiddle without luck. Could you help me here? (or even add a format 3 in your example if there isn't too much to ask for). I know that the accepted answer cover this, but yours is great too
-
VisioN about 10 years@Michel Here is a super extended version, which supports different delimiter types: jsfiddle.net/hAfMM/610.
-
Julien de Prabère about 10 years@VisioN : Your short solution does not work for long number. It is necessary to replace the \. by a \b (for word boudarie) like I proposed on Jan 4'12 (see infra).
-
VisioN about 10 years@JuliendePrabère Please give an example of a long number which doesn't work with this approach.
-
Mike Causer about 10 years
toCurrency('123456.7890')
returns123,456.7,890
. IMHO, there should not be any commas in the decimal places. Other than that, looks good! -
McGuireV10 almost 10 years@RobQuist He almost certainly meant flipped in comparison to what is in the code and not as an invitation to re-fight the Revolutionary War.
-
nikhil almost 10 yearsif someone want to undo the formatMoney back, here's the code: String.prototype.undoFormatMoney = function () { var tempVals; var val = this; var sign = ((val.split('$')[0]) == "-") ? "-" : "", val = val.split('$')[1]; tempVals = val.split(','); val = 0; var adjPlaces = 1; len1 = (tempVals.length) - 1; for (var i = len1, j = 0; i >= 0; i--, j++) { if (j > 0) { adjPlaces = j * 1000; } val = val + ((tempVals[i]) * adjPlaces); } return sign + "" + val; };
-
Neil Monroe almost 10 yearsSafari definitely implements toLocale functions differently. The locale date formats also produce different output than every other major browser.
-
Neil Monroe almost 10 yearsIt is still considered alpha stage, so use cautiously, but great find.
-
Neil Monroe almost 10 yearsI like the fact that you can do the reverse--pass a formatted currency string and get the numeric value.
-
Jared Beck over 9 yearsMDN has an example of checking for support for locales and options arguments
-
Arsha over 9 yearsImproved from your method 2. change from var a = this.toFixed(precision).split('.'), to var multiplier = Math.pow( 10, precision + 1 ), wholeNumber = Math.floor( this * multiplier ); var a = Math.round( wholeNumber / 10 ) * 10 / multiplier; if (String(a).indexOf('.') < 1) { a += '.00'; } a = String(a).split('.'), Don't use toFixed because it is buggy.
-
Arsha over 9 yearsconsole.log(parseFloat('4.835').toFixed(2)); > 4.83 console.log(parseFloat('54.835').toFixed(2)); > 54.84 console.log(parseFloat('454.835').toFixed(2)); > 454.83 console.log(parseFloat('8454.835').toFixed(2)); > 8454.83 all of these value's decimal should be .84 not .83
-
Nico over 9 yearsThis answer was almost there for me, but I needed it to be rounded to the nearest penny. This is what I used amount.toLocaleString('en-GB', { style: 'currency', currency: 'GBP', maximumFractionDigits: 2 });
-
hlascelles over 9 yearsAs previous commenters have mentioned, this is not just confusing, it is also wrong. It gives 49.65.formatMoney(1,'.',',') => 49.6
-
CookieCoder over 9 yearsI was using this, but got an error, so adding var myMoney = Number(myMoney).toFixed(2); adding Number() worked.
-
Betty Mock over 9 yearsNegative numbers worked fine for me. What I like about this is that there isn't very much code and it doesn't depend on a regex.
-
Kushal Shah about 9 yearsKeep voting this one up as it's the best solution (if not the best answer).
-
Daniel Barbalace about 9 yearsThe above code does rounding to the number of digits you want. See the example and type in 1.237 in the input box.
-
Lance Anderson about 9 yearsDoesn't seem to work in Safari. It just returns the number as a String without any formatting.
-
stackoverfloweth almost 9 yearsNot consistent across all browsers :/
-
Ken Palmer almost 9 yearsThanks for the heads-up @godmode. What browsers did you see problems with?
-
stackoverfloweth almost 9 yearsSafari 8.0.6 it wasn't trimming decimals, inserting "$", or adding commas
-
VisioN almost 9 years@Gyrocode.com Why
$&
approach didn't work for you? -
Pier-Luc Gendreau almost 9 yearsExtra super extended version: jsfiddle.net/hAfMM/2269 Integrates currency symbol
-
Chase Sandmann almost 9 yearsWhy didn't you just do
(parseInt(p[0])).toLocaleString()
? -
Wayne almost 9 yearsBecause that function can produce different results in different locales. That may very well be what you want, but it doesn't answer the specific formatting question directly. (Also, notice the date on the question/answers here.)
-
Bhargav Nanekalva almost 9 yearsAsked for a JS solution!
-
Peter almost 9 yearsI get wrong number output while entering negative values to ins1000Sep().
-
tggagne over 8 yearsUptick the idea for using toLocaleString(), but downtick for the float. As was commented earlier, currency should never be stored in a float.
-
Ken Palmer over 8 yearsThanks @tggagne, you are correct. Bad oversight on my part.
-
Guy Schalnat over 8 yearsNo longer in alpha (or beta). This seems to be very useful while we wait for Safari to meet the new standard and for IE < 11 to die.
-
Doug S over 8 years@acorncom Why do you say there is "little browser support"? The Number object has been around since Javascript 1.1. Please provide a reference that backs up your claim.
-
Clain Dsilva over 8 yearsWhy this is not chosen as the best answer? Its has covered all possible options
-
Deji over 8 yearsSo many sourpusses in these comments. Wow, sure the code may not be the prettiest, but if you're worth your salt as a 'programmer', it is definitely not overly complicated or undecipherable, assuming you know how to read code, that is. And who ever maintains code they've copied and not created themselves anyway?
-
Andres Felipe over 8 yearsok awesome code, unfortunately i can't understand many things but it was very useful tks
-
aross over 8 years@Deji, coding style standards, naming things, code structuring, commenting and annotating be damned.
-
Deji over 8 years@aross Is this question related to coding style standards, "naming things", code structuring, commenting and annoting? Is you vaguely mentioning any of those concepts providing any reasons that the particular code above is not a fitting answer? No...
-
aross over 8 years@Deji So you would even consider obfuscated code a good answer?
-
Deji over 8 years@aross Depends on the question. That's what I think you're not getting here - the comments aren't for judging the quality of the code, but the quality of the ANSWER. I really shouldn't have to explain how answers to questions are usually judged for quality...
-
Kevin B over 8 yearsFortunately this is a community wiki, so any of you complaining about the code format/readability can just fix it on your own.
-
Anton P Robul about 8 yearsThis function is incorrect: > (2030).formatMoney(0, '.', ' '); < "2 03 0"
-
Anton P Robul about 8 yearsThis function are incorrect: > (2030).toMoney(0, '.', ' '); < "2 03 0"
-
Anton P Robul about 8 yearsThis is only one correct function: > number_format(2030, 0, '.', ' ') < '2 030' Great ! Thanks
-
RationalDev likes GoFundMonica about 8 yearsThe fork Numbro seems to get more love as Numeral.js seems abandoned: github.com/foretagsplatsen/numbro
-
RationalDev likes GoFundMonica about 8 yearsaccounting.js doesn't seem maintained lately. One fork with recent changes is github.com/nashdot/accounting-js
-
wosis about 8 yearsStrange code, to my mind, ex. value gets re-assigned twice within the function, makes it very dificult to debug. With decimalPlaces = 0, the value is implicitly rounded by "toFixed", which is not indented in my case.
-
Liam almost 8 years
-
VisioN almost 8 years@1111161171159459134 This is just a short and fast alternative to
Math.floor(n)
. If you want to make it JSHint compliant, replace this bit accordingly. -
MSC almost 8 yearsI like this and am happy that it works with Indian digit grouping.
-
Connor Simpson almost 8 yearsSmall and simple. Thank you.
-
Admin over 7 yearsHow did such a terrible practice get 1K+ upvotes? Not to mention it was written pre-minified.
-
Trasiva over 7 yearsVoting this one because it's a stupidly simple answer that works natively.
-
Mohammed Farooq over 7 yearsAwesome code. Can it be possible to do reverse like un-format (12.345.678,90 to 12345678.9) similarly any currency format to normal number @VisioN
-
VisioN over 7 years@MohammedFarooq Sure, as easy as this: jsfiddle.net/hAfMM/3934.
-
Mohammed Farooq over 7 years@VisioN- Thanks, But i dont need to pass (comma & dot ) as parameter. I need to return a number if i pass (12.345.678,90 to 12345678.9) or (12,345,678.90 to 12345678.9). EIther euro or standard format to normal number
-
VisioN over 7 years@MohammedFarooq To make this working the script should know what style your number is formatted with. It can't automatically detect if dot or comma is used as a separator for sections or a decimal part. Otherwise you have to use strict number format, so the parser may guess which character separates what part.
-
Matrix over 7 yearsHow can I do to format "12514652" number? I can't call
12514652.format()
like ruby... so? -
Besat over 7 yearsThanks for your answer. I have a question though.How can I eliminate e+ from the number? for example 1000000000000000000000 now is formatting like: $ 1e+21 but I would like it to be like: $ 1,000,000,000,000,000,000,000.00
-
VisioN over 7 years@Besat That's a tricky one but we can use a nice workaround with a custom
Number.prototype.toFixed
method, that can implicitly transform numbers in scientific notation to their full length string representation. Please see the solution here: jsfiddle.net/hAfMM/4027. -
Besat over 7 yearsWonderful! Thanks!
-
Faisal over 7 yearshow to make arr[i].price example, formatted to this? this code work great! @VisioN
-
Charlie Dalsass over 7 yearsGreat code snippet, thank you. However, be careful, as it will not work on IE because default parameters are not supported, and "const" and "let" not supported in <IE11. Ue this to fix: + moneyFormat: function (price, sign) { + if (!sign) sign = '$'; + pieces = parseFloat(price).toFixed(2).split('') + var ii = pieces.length - 3
-
synthet1c over 7 yearsNo worries @CharlieDalsass. I would recommend using babel to compile it down to ES5 for production code.
-
adamwdraper over 7 yearsNumeral.js is active again.
-
Akshay Vijay Jain over 7 yearsin order to handle negative number properly prepend following code before returning
num=="-" ? acc:
<br>i.e. function passed to reduce method will be <br>function(acc, num, i, orig) { return num=="-" ? acc:num + (i && !(i % 3) ? "," : "") + acc; }
-
JensB over 7 yearsBecause I dont like code I can't read I rewrote it to be more developer friendly here: syntaxwarriors.com/p/18/Format-currency-in-Javascript Pretty much the same thing but readable.
-
flq over 7 yearsPretty sure a quite high % of browsers now support this. This should be upvoted much more.
-
Victor Dombrovsky over 7 yearsA non-minified version: josscrowcroft.com/2011/code/… (see "JavaScript Money Format").
-
VisioN over 7 years@aross Unfortunately Intl API is still not available in many browsers which are widely used and this solution will make sense when compatibility requirements feature IE9, IE10, Safari 9, etc.
-
VisioN over 7 years@aross Often including 2-3 lines of code is faster and easier than embedding 50+Kb library to get the same result. It depends on the thing you are actually doing. I still use this code in my projects when I simply need to format a number in a straightforward format.
-
VisioN over 7 years@aross My experience tells the opposite: this code is enough in 90% of all the cases. I don't know what Indial digit grouping is but I'm sure this solution can be easily customised for it. Get me right, I don't say that this answer is the best one nowadays in 2017 but I'm quite confident that developers will still find it useful.
-
Evgeny about 7 yearsThis is fully supported as of 2017 and should be the only correct answer
-
Gerard ONeill about 7 yearsVisioN, you are correct -- I'm selecting the first of your short solutions -- which, by the way, is a brilliant regex! Thank you for sharing it, I've gained a neuron.
-
Admin almost 7 yearsBut how to do it as Euro Currency?
-
Admin almost 7 yearsBut how to do Euro currency? 1.000,00 Euro?
-
synthet1c almost 7 years@YumYumYum I added a full example with more formatting options to allow for more flexibility.
-
Admin almost 7 years
$('#price').val( accounting.formatMoney(OOA, { symbol: "€", precision: 2,thousand: ".", decimal :",",format: "%v%s" } ) );
- show 1.000,00 E -
Mark Carpenter Jr almost 7 yearsThe MDN Documentation for anyone who would like to see the full set of options.
-
Mark Carpenter Jr almost 7 yearsThe
toLocaleString()
prototype, does the same thing with less code. and is more robust. Answered Here -
Ethan almost 7 yearsWow, this is a really great answer. Should be top.
-
Patrick Roberts almost 7 yearsI personally think this solution is garbage. You don't use sensical variable names, you modify the
prototype
of a built-in with an enumerable property, and your code doesn't even make sense, even if it does work. -
Sprose over 6 yearsThis is a great answer and I have it working with a dynamic currency value so if use is in Europe then it changes to EUR and shows the euro sign. Works a treat!
-
aross over 6 yearsCare should be taken that there is an old version of
toLocaleString
that uses the system locale, and a new (incompatible) one that comes from ECMAScript Intl API. Explained here. This answer seems to be intended for the old version. -
Captain Hypertext over 6 yearsThis answer is somewhat outdated now. See the answer about Intl.numberformat below
-
aron about 6 yearssimple, but no comma for 1,000
-
Serj Sagan about 6 yearsHorrible use of variable names!
-
Horacio almost 6 yearsIf for some reason you don't want cents, you can change decimal precision with:
minimumFractionDigits: 0
-
Burak almost 6 yearsNot sure why this is so highly voted, but this doesn't do what OP is asking for. For example,
10000
would turn into"10,000"
and not"10,000.00"
which is the desired behavior for currency formatting. -
Alexander almost 6 yearsRegarding @Burak comment. I don't think this is the case. For me the code "var currency = "$"+Number(someNumber.toFixed(2)).toLocaleString()" turns var someNumber = 2345667.7899; into $2,345,667.79 which is what I need.
-
flyandi almost 6 yearsWorks great in React Native as well!
-
Burak almost 6 years@Alexander but what if someNumber is "234567" or "234567.8"? Then you have zero or one decimals, instead of two, which isn't what OP wants and generally seems undesired for currency formatting too.
-
Alexander almost 6 yearsYes, you are correct. The one I now use is the prototype Number.prototype.formatMoney which is identified below.
-
Bacon Brad almost 6 yearsCode on this site should favor readability for people, not web browsers.
-
Kabir Sarin over 5 yearsIt's 2018 and this is basically supported everywhere. This should be the correct answer.
-
Avernikoz over 5 yearsMy TS version that works for many cases:
export const formatNumberToUSFormat = (numberToFormat: number | string) => { const stringNumber = numberToFormat.toString() return stringNumber.match(/\./g) ? stringNumber.replace(/\d(?=(\d{3})+\.)/g, '$&,') : stringNumber.replace(/\d(?=(\d{3})+$)/g, '$&,') }
-
Robin Wilson over 5 yearsIf the date could be null then you need to call the function like this:
formatMoney(someDate, 2)
instead ofsomeDate.formatMoney(2)
otherwise you get "Uncaught TypeError: Cannot read property 'value' of null" when it is. -
Nick Grealy about 5 years@Horacio / Nico - See earlier answer: stackoverflow.com/a/18994850/782034
-
Caio Mar almost 5 yearsI'm surprised no one mentioned that the line
j = (j = i.length) > 3 ? j % 3 : 0;
is calling for j before it is defined -
Jakub Keller almost 5 yearsThis code is hard to follow. At least give some names to the parameters.
-
oldboy almost 5 yearsthe best answer by far
-
n8jadams almost 5 yearsI needed something to work in both the browser and in an old version of Node. This worked perfectly. Thanks
-
avenmore over 4 yearsThis does not get the commonly used format for en-ZA/ZAR (South Africa) correct, so if you are in a outlying region you may be at the mercy of what an outsider has guessed your format should be.
-
Nick Grealy over 4 years@avenmore works for latest versions of Chrome/Firefox/Safari. I hate to ask... but what browser & version are you testing on?
-
avenmore over 4 yearsLatest and greatest :) FF69, Chrome76, etc. "R 2 500,00" is not what we use here, it should be "R 2,500.00", same as en-GB.
-
Nick Grealy over 4 years@avenmore ... interesting... I did a bit of investigation, and TLDR; comma is the official decimal separator for South Africa. "When South Africa adopted the metric system, it adopted the comma as its decimal separator, although a number of house styles, including some English-language newspapers such as The Sunday Times, continue to use the full stop" - en.wikipedia.org/wiki/Decimal_separator. However, you can switch formats by using
(2500).toLocaleString("en-GB", {style: "currency", currency: "ZAR", minimumFractionDigits: 2})
-
avenmore over 4 years@Nick Grealy Thanks for the investigation, it is the bane of South African software people - having things break from an unexpected comma. I did try the params you suggest but it produced "ZAR 2,500.00", also not acceptable.
-
Simon East over 4 yearsThis option doesn't put a comma between the thousands. :-(
-
Tim over 4 years
minimumFractionDigits: 2
just what I was looking for! -
ryanm over 4 yearsWARNING! The non-ES6 code is not functional as of 10/31/2019, I am surprised it got so many upvotes! Please correct the following simple cases: 100000 (results in 100000.00) and 1000000 (results in 1,000000.00)
-
acido over 4 yearsThe Number() is mandatory if the var is a string or any other type. This helped me a lot! thanks for sharing it.
-
beliha over 4 yearsnon ES6 code doesn't work, there is somethign wrong with the regExpression used, I haven't brushed up on my reg ex in years so I can't fix it unfortunatley
-
Matt Jensen over 4 yearsSupport as far back as Internet Explorer 11 (IE 11), with all major browsers supporting as well.
-
beliha about 4 yearsCleaner non ES6: function formatMoney(amount, decimalCount, decimal, thousands) { decimalCount = Math.abs(decimalCount); decimalCount = isNaN(decimalCount) ? 2 : decimalCount; var negativeSign = amount < 0 ? "-" : ""; var i = parseInt(amount = Math.abs(Number(amount) || 0).toFixed(decimalCount)).toString(); var j = (i.length > 3) ? i.length % 3 : 0; return negativeSign + (j ? i.substr(0, j) + thousands : '') + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + thousands) + (decimalCount ? decimal + Math.abs(amount - i).toFixed(decimalCount).slice(2) : ""); }
-
Amzad Khan about 4 yearsAfter decimal you want only two (2) digits for example, suppose your currency format is this 22.2737, at that time you can use following solution for getting result in this format 22.27, function currencyFormat(num){ return parseFloat(num).toFixed(2); } var moneyWithDecimal = currencyFormat(22.2737); alert(moneyWithDecimal );
-
olaoluwa_98 about 4 yearsThis is an awesome solution! but I tried it for a number starting with 0 e.g
(012345).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,')
It returns "5,349.00" instead of "12,345.00" -
VisioN about 4 years@olaoluwa_98 Numbers that start with zero are considered to be octal literals, so
012345
is5349
in decimal notation. You are not allowed to use octal literals in strict mode. -
Cegone almost 4 yearsI agree with @Burak, why this is best answer so far.. anyone tried? it is not giving expected output
-
user1556937 almost 4 yearsis there a way to discredit this answer. its no longer relevant.
-
RkuangDev over 3 yearsis there a way to reverse this getting $2,500.00 back to a string like 2500.00
-
aross over 3 years@RkuangDev Sure, but you need to know the decimal separator used. If it's a dot (easiest scenario), this will work:
parseFloat('$2,345.67'.replace(/[^0-9.]/g, ''))
. Beware of floats for currency, of course -
Paulo Bueno over 3 yearsMy 2 cents: for non-imperial(ists) guys
(7642818.78).toFixed(2).replace(".",",").replace(/\d(?=(\d{3})+\,)/g, '$&.')
-
TheGeekZn over 3 yearsEveryone just vote-down this answer so the proper answer can be more visible
-
Olawale Oladiran over 3 yearsHow come this is not the accepted answer. Works beautifully!
-
Martin Braun over 3 yearsI'd like to nominate this answer to be the most upvoted answer that needs to be down voted for heavens sake.
-
guilieen over 3 yearsHow to do that with a event in input when typing?
-
wilmol over 3 yearsThese inbuilt format functions are inconsistent (require locale data...) so this regex is a lifesaver.
-
Marco Demaio over 3 years@AntonPRobul it's not true you can test it with JS FIddle link added in the answer,
(2030).toMoney(0, '.', ' ');
produces this:"2 030"
which is the expected result since you are telling the function to use a single whitespace as thousands separator. -
Mike Jarema about 3 yearsThe "Custom function" code is incorrect. For example when running the code snippet, 1234567.12 is returned as 1,234567.12, it's just plain wrong.
-
Harrison about 3 yearsThis is amazing! Should be the best answers,!
-
Aljosha Novakovic about 3 yearsAdd
maximumFractionDigits: 0
if you want the answer in the form of$2,500
. So it would be:return (num).toLocaleString('en-US', {style: 'currency', currency: 'USD', maximumFractionDigits: 0 });
-
aross about 3 years@AljoshaNovakovic Correct, that's already in the answer as well :)
-
Aljosha Novakovic about 3 yearsahh yeah didn't see in the comments. Good answer!
-
JotaPardo about 3 yearsI had to add the line
let j = 0;
before using j. Issues with the code in some developers browsers... But in other cases still working. Weird. -
JotaPardo about 3 yearsI had to add the line
let j = 0;
before using j. Issues with the code in some developers browsers... But in other cases still working. Weird. -
Peter Mortensen about 3 yearsAn explanation would be in order. E.g., what is the idea/gist? How is it different from previous answers?
-
Wayne about 3 yearsThe edit to support negative numbers doesn't actually seem to work
-
Peter Mortensen almost 3 yearsDoes it work? 10 years should be enough to have figured it out. Or is it a rhetorical question?
-
Peter Mortensen almost 3 yearsAn explanation would be in order.
-
Peter Mortensen almost 3 yearsAn explanation would be in order.
-
Peter Mortensen almost 3 yearsHow can it be the best one if it produces wrong output?
-
Peter Mortensen almost 3 yearsAn explanation would be in order. At a minimum a statement about what range of numbers it is supposed to work for. You could also include some sample input and output (e.g., you could use some sample inputs from other answers).
-
Peter Mortensen almost 3 years@Bhargav Nanekalva: It is actually in JavaScript.
-
Peter Mortensen almost 3 yearsThe first link is (effectively) broken: "Page not found"
-
Peter Mortensen almost 3 yearsRe "a lot of bugs in the code": Three places that look suspicious:
l=l-v.length
(is in a Boolean context/comparison),return "\"+"+f+"+\"";
(missing escapes?), andreturn new Function("_f_money,_f_flt,_f_hex", cmd)(_f_money,_f_flt,_f_hex);
(is that valid syntax? - not a rhetorical question). -
Peter Mortensen almost 3 yearsAn explanation would be in order. E.g., what is the purpose of
ar[0] | 0
? -
Peter Mortensen almost 3 yearsIs
<script language=="Javascript">
valid syntax (not a rhetorical question)? -
Peter Mortensen almost 3 yearsWhat is the difference between
theEvent.preventDefault
andtheEvent.preventDefault()
? (Used in the same construct) -
Peter Mortensen almost 3 yearsAn explanation would be in order. For example, how can it be so simple and not covered by any of the previous more than 50 answers over 9 years (at the time)?
-
aross almost 3 yearsDo you have anything different from this answer? stackoverflow.com/a/16233919/1000608
-
aross over 2 yearsBy choosing the regex answer while your requirements were more complicated you put yourself in a tough spot. You could just have used
maximumFractionDigits
, as described here. -
Md. Rejaul Karim over 2 yearsNot work with negative number
-
Wayne over 2 years@Md.RejaulKarim Yeah, that was a bad edit. I've fixed it with a much more elegant solution. (You always want to output the value of
num
prepended toacc
; the only question is whether to include a comma between the two. That's the check that should have been updated.) -
Diego Leonvendagar over 2 yearsIm using this solution today. But when there are no decimal digits in the original number, its showing the ".00" anyway. Is there a format to allow 2 decimal numbers but that hides them when they aren't needed?
-
Qiqo about 2 yearsupvoting this in 2022. This should be the accepted answer for wide compatibility and simplicity (as it should be)
-
Josh Bonnick about 2 yearsI had an issue with Chrome version 87 and below using
maximumFractionDigits: 0
- refuses to use 0 as it's value. -
aross about 2 years@JoshBonnick That probably happened due to incomplete/outdated libICU used. Possibly platform related, if Chrome tries to use (or tried to) the system ICU rather than a shipped one.
-
Josh Bonnick about 2 years@aross It ended up being because the default value for
minimumFractionDigits
was 2 - so min 2 and max 0 caused aInvalid range error
- took me a while to figure this out, v88+ just accepted a max of 0 -
aross about 2 years@JoshBonnick Funny, Firefox never had this issue so sounds like a Chrome bug then.