Javascript Number.toFixed() Method

Posted October 29, 2007 at 8:03 AM by Ben Nadel

Tags: Javascript / DHTML

While reading the book, Learning jQuery, I came across a Javascript method that I had never heard of. The .toFixed() method, which can only be called on numeric values, will return a string representation of the number with the given number of decimal places. For example, if you wanted to return a dollar formatted version of a number, you could call something like this:

  • ("$" + (15).toFixed( 2 ))

This would take the number 15 and return the string, "15.00", to which we would prepped the dollar sign.

This is a function that I wish I had known about a long time ago. Formatting numbers has always been somewhat of a hassle in Javascript, especially after coming from ColdFusion where formatting numbers is an all-to-easy task. To see how this method works in detail, I decided to run a few tests on it:

  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>Javascript .toFixed() Example</title>
  • </head>
  • <body>
  •  
  • <script type="text/javascript">
  •  
  • // Create a string representation of the number
  • // that we want to format.
  • var StringValue = "1234.56789";
  •  
  • // Create a numeric representation of the number
  • // that we want to format by parsing the float
  • // value out of the string value.
  • var NumericValue = parseFloat( StringValue );
  •  
  •  
  • // The .toFixed() is a method of the Numeric object.
  • // But, let's try to call it on the string to see if
  • // there is any implicit type-casting done for us.
  • try {
  •  
  • document.write(
  • StringValue.toFixed( 2 )
  • );
  •  
  • } catch( Error ){
  •  
  • document.write(
  • "String value did not work<br />"
  • );
  •  
  • }
  •  
  •  
  • // We know that it works on the numeric object,
  • // but let's loop over it to see how it works before
  • // and after we pass the known number of digits.
  • for (intI = 0 ; intI < 10 ; intI++){
  •  
  • document.write(
  • NumericValue.toFixed( intI ) + "<br />"
  • );
  •  
  • }
  •  
  • </script>
  •  
  • </body>
  • </html>

While I know that it won't work on a String value, I ran a test on the string value of the number. This was just to see if Javascript would perform any kind of implicit data type conversion for us. Running this code, we get the following output:

String value did not work
1235
1234.6
1234.57
1234.568
1234.5679
1234.56789
1234.567890
1234.5678900
1234.56789000
1234.567890000

As you can see, it only works on numeric values. Also, you will notice that it rounds to the given decimal place (or to the closest integer if given "0" as the number of digits to display).

Very cool stuff; this will be a good tool to have in the Javascript tool belt.




Reader Comments

Oct 29, 2007 at 9:10 AM // reply »
9 Comments

Great find, Ben! I've always been frustrated with trying to format numbers in JavaScript, too.


Oct 29, 2007 at 9:56 AM // reply »
21 Comments

There are several ways to convert strings to numbers in JavaScript. One way is the parseFloat that you've shown here, but you can convert it directly into a number with the following:
var str = Number('1234.56789');

An alternate method of moving a string to number is to subtract 0 from it:
var str = '1234.56789' - 0;
alert(str.toFixed(2)); // assuming that the string is actually a number

Not that it's much, but it is a tiny bit faster than parseFloat, at least on my system, but the differences don't show up until you're well above 10,000 iterations. At 100,000 iterations it's approximately 265 milliseconds for minus zero to 469 milliseconds for the parseFloat method, so for most cases it's better to with the more readable parseFloat.

FWIW: try-catch is fairly expensive, it would probably be better to test a variable for the existence of the toFixed method than to use a exception:

var StringValue = '1234.56789';

if(StringValue.toFixed && typeof StringValue.toFixed === 'funciton'){
// write to page
}
else{
// something did not work
}

Also, you're assuming that the value that is in NumericValue is actually a number after calling parseFloat, but parseFloat will return NaN (Not a Number) if the string can't be converted into a float, so you should either have done a RegExp match on your string to make sure it is a number that you can work with, or check for NaN before you do any other processing that relies on the value being a number. For example:

var StringValue = 'This is no longer a number 1234.56789';
var NumericValue = parseFloat(StringValue);

if( !isNaN(NumericValue) ){
// do your loop
}
else{
// something went wrong
}

anyway, just had a moment so I rambled, hope you don't mind. :-)


Oct 29, 2007 at 6:20 PM // reply »
10,640 Comments

@Danilo,

Thank you for the most excellent feedback. Very good suggestions here. I like the idea of using the Numeric() object constructor for creating numbers. I wonder, does it return NaN if you pass in a non-numeric value? I can test that on my, I was just thinking away...


Oct 29, 2007 at 7:01 PM // reply »
21 Comments

@Ben,

Yes, Number(str) will be NaN if the value of str isn't converted into a number. Make sure that you use isNan() to check for values being NaN because NaN does not equal NaN.

var str = 's1234.56789';
var n1 = Number(str);
var n2 = Number(str);

alert(n1 == n2);

This alerts false even though n1 and n2 look like they might be equal, but because they are NaN they aren't.


Oct 29, 2007 at 10:17 PM // reply »
168 Comments

In addition to the number-conversion methods already discussed here so far, you can also use the unary plus operator, e.g. +'10'. This is nice and cheap (performance-wise) and only adds one character.

As for toFixed(), you can save one character by using a space after a numeric literal, e.g. 10 .toFixed(2). If your numeric literal includes a decimal place you can even drop the space, e.g. 10.0.toFixed(2).


Nov 29, 2007 at 2:26 AM // reply »
1 Comments

I tried to perform a rounding operation - however for numbers have the decimal point position > 14 (i.e. 13 digits exist before the decimal place) the rounding is incorrect. Is it because the number goes out of range for 'integer' in javascript? For instance, the above method fails for the number
12345678912345.123456


Nov 29, 2007 at 7:13 AM // reply »
10,640 Comments

@Gayatri,

While I cannot say one way or the other, what you are suggesting sounds correct. That's a huge number! What are you doing? Calculating the number of bacteria in a culture or something (I sure hope you aren't working with dollars or that would just make me feel sad and insignificant :)).


May 15, 2008 at 2:44 PM // reply »
1 Comments

That was really helpful, wanted you to know, thanks :)


Jun 30, 2009 at 2:46 AM // reply »
1 Comments

Thanks for the info ... :)


edu
Aug 21, 2009 at 4:07 PM // reply »
1 Comments

What happens with this number 123456789012345.1

Example:
----------------------
a="123456789012345.1"
n = parseFloat(a);
s = n.toFixed(2);
----------------------

The result of s is: 123456789012345.09
it is wrong? why?


Sep 6, 2009 at 1:26 PM // reply »
10,640 Comments

@Edu,

That's probably an issue with the ability to store FLOAT numbers past a certain size. That is a HUGE number you have there - probably larger than the script engine can store with accuracy.


Feb 19, 2010 at 6:33 AM // reply »
1 Comments

var percent = (source1.value*1) * (source2.value*1);
source3.value = percent.toFixed(2);

Thanks


Feb 24, 2010 at 8:10 PM // reply »
2 Comments

I actually thought it was a JQuery only function when I saw it in the JQuery ui.slider. This is an overlooked function similar to how the second parameter of String.parseInt() is overlooked.

See: http://www.bucabay.com/web-development/base-conversion-in-javascript/

for the example of String.parserInt


Mar 19, 2010 at 9:44 AM // reply »
10,640 Comments

@Bucabay,

That's cool - I didn't realize that Javascript has a base() conversion method. That is super useful.


Mar 19, 2010 at 10:57 AM // reply »
2 Comments

It doesn't have a base() method, but it can be put together simply with:

Math.base = function(n, to, from) {
return parseInt(n, from || 10).toString(to);
};


Mar 22, 2010 at 7:51 PM // reply »
10,640 Comments

@Bucabay,

Oops - must have read too quickly. When I saw Math.base, I just assumed it was core. That said, I was not even aware that toString() could take an argument. I'll have to look into that as well.


Jan 29, 2011 at 11:54 PM // reply »
2 Comments

I found this post while searching google. Quite surprising too, since google usually displays relatively old results but this one is very recent! Anyway, very informative, especially since this is not something many people tend to write something good.


Jan 10, 2012 at 2:23 PM // reply »
1 Comments

Very userul, just had to say thanks!



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »