FAQ Topic - How do I convert a Number into a String with exactly 2 decimal places? (2008-06-20)

Discussion in 'Javascript' started by FAQ server, Jun 20, 2008.

  1. FAQ server

    FAQ server Guest

    -----------------------------------------------------------------------
    FAQ Topic - How do I convert a Number into a String with
    exactly 2 decimal places?
    -----------------------------------------------------------------------

    When formatting money for example, to format 6.57634 to
    6.58, 6.5 to 6.50, and 6 to 6.00?

    Rounding of x.xx5 is uncertain, as such numbers are not
    represented exactly. See section 4.7 for Rounding issues.

    N = Math.round(N*100)/100 only converts N to a Number of value
    close to a multiple of 0.01; but document.write(N) does not give
    trailing zeroes.

    ECMAScript Ed. 3.0 (JScript 5.5 [but buggy] and JavaScript 1.5)
    introduced N.toFixed, the main problem with this is the bugs in
    JScripts implementation.

    Most implementations fail with certain numbers, for example 0.07.
    The following works successfully for M>0, N>0:

    function Stretch(Q, L, c) { var S = Q
    if (c.length>0) while (S.length<L) { S = c+S }
    return S
    }
    function StrU(X, M, N) { // X>=0.0
    var T, S=new String(Math.round(X*Number("1e"+N)))
    if (S.search && S.search(/\D/)!=-1) { return ''+X }
    with (new String(Stretch(S, M+N, '0')))
    return substring(0, T=(length-N)) + '.' + substring(T)
    }
    function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
    function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }
    Number.prototype.toFixed = function(n){ return StrS(this,1,n) };

    http://www.merlyn.demon.co.uk/js-round.htm

    http://msdn2.microsoft.com/en-us/library/sstyff0z.aspx


    --
    Postings such as this are automatically sent once a day. Their
    goal is to answer repeated questions, and to offer the content to
    the community for continuous evaluation/improvement. The complete
    comp.lang.javascript FAQ is at http://jibbering.com/faq/index.html.
    The FAQ workers are a group of volunteers. The sendings of these
    daily posts are proficiently hosted by http://www.pair.com.
    FAQ server, Jun 20, 2008
    #1
    1. Advertising

  2. FAQ server

    Evertjan. Guest

    FAQ server wrote on 20 jun 2008 in comp.lang.javascript:

    > -----------------------------------------------------------------------
    > FAQ Topic - How do I convert a Number into a String with
    > exactly 2 decimal places?
    > -----------------------------------------------------------------------


    I would like to add my latest version for 'any' integer d >= 0:

    function round(n,d){
    n = Math.floor(n*Math.pow(10,d)+.5);
    if (d<1) return n;
    var s = Math.abs(n).toString();
    while (s.length<d+1) s = '0' + s;
    return ((n<0) ?'-':'') + s.slice(0,-d) + '.' + s.slice(-d);
    };

    I do not trust internal rounding to be according to my definition.
    I like the slice() string manpulation possibilities.

    Shoot?

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jun 20, 2008
    #2
    1. Advertising

  3. FAQ server

    yukabuk Guest

    Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places? (2008-06-20)

    You should write this...

    var numberObj = new Number(6.57634);
    var formattedNumber = numberObj.toFixed(2);


    Graham
    yukabuk, Jun 20, 2008
    #3
  4. FAQ server

    Evertjan. Guest

    Re: FAQ Topic - How do I convert a Number into a String with exactly 2 decimal places? (2008-06-20)

    yukabuk wrote on 20 jun 2008 in comp.lang.javascript:

    > You should write this...
    >
    > var numberObj = new Number(6.57634);
    > var formattedNumber = numberObj.toFixed(2);


    You? Why?

    What are you responding on?

    [please always quote on usenet]

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jun 20, 2008
    #4
  5. In comp.lang.javascript message <Xns9AC39D119DD31eejj99@194.109.133.242>
    , Fri, 20 Jun 2008 13:26:35, Evertjan. <>
    posted:
    >FAQ server wrote on 20 jun 2008 in comp.lang.javascript:
    >
    >> -----------------------------------------------------------------------
    >> FAQ Topic - How do I convert a Number into a String with
    >> exactly 2 decimal places?
    >> -----------------------------------------------------------------------

    >
    >I would like to add my latest version for 'any' integer d >= 0:


    Fails, I think, for n=1.11, d>21 ; also for n = infinity, NaN. Put your
    function, followed by return round(X, N) in the second textarea of
    <URL:http://www.merlyn.demon.co.uk/js-round.htm#TRPF> and press the
    button.

    >function round(n,d){
    > n = Math.floor(n*Math.pow(10,d)+.5);
    > if (d<1) return n;
    > var s = Math.abs(n).toString();
    > while (s.length<d+1) s = '0' + s;
    > return ((n<0) ?'-':'') + s.slice(0,-d) + '.' + s.slice(-d);
    >};
    >
    >I do not trust internal rounding to be according to my definition.
    >I like the slice() string manpulation possibilities.
    >
    >Shoot?


    The one in the FAQ includes provision for a fixed number of places, or
    characters, before the decimal separator, which is useful for tables in
    <pre>, etc.

    It would be nicer, for those who recall FORTRAN convention, to use x
    instead of n. And, to please IUPAP/SUNAMCO. .5 should be 0.5 .

    Note that I don't use what the FAQ says.

    --
    (c) John Stockton, nr London UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
    <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
    <URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
    <URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.
    Dr J R Stockton, Jun 20, 2008
    #5
  6. FAQ server

    Evertjan. Guest

    Dr J R Stockton wrote on 20 jun 2008 in comp.lang.javascript:

    >>I would like to add my latest version for 'any' integer d >= 0:

    >
    > Fails, I think, for n=1.11, d>21 ; also for n = infinity, NaN.


    With quoted 'any', I ment any reasonable. ;-)

    Catching all possibilities makes the code sound but unreadable for
    instruction.

    > Put your
    > function, followed by return round(X, N) in the second textarea of
    > <URL:http://www.merlyn.demon.co.uk/js-round.htm#TRPF> and press the
    > button.


    Sorry, John, your server seems down.

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jun 21, 2008
    #6
  7. Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places? (2008-06-20)

    On Jun 21, 8:53 am, "Evertjan." <> wrote:
    > Dr J R Stockton wrote on 20 jun 2008 in comp.lang.javascript:
    >
    > >>I would like to add my latest version for 'any' integer d >= 0:

    >
    > > Fails, I think, for n=1.11, d>21 ; also for n = infinity, NaN.  

    >
    > With quoted 'any', I ment any reasonable. ;-)
    >
    > Catching all possibilities makes the code sound but unreadable for
    > instruction.


    It is only necessary to include a test that s is all-digit, such as
    if (/\D/.test(d)) return n // cannot cope

    IMHO, d=0 should be allowed; it should give results such as "3." which
    is deprecated but not wrong.


    > Sorry, John, your server seems down.


    <QUOTE>
    We will be carrying out planned maintenance of our Web Hosting
    platform as follows:
    Saturday 21st June between 00:01 and 20:00 Hrs BST
    Saturday 28th June between 00:01 and 04:00 Hrs BST
    Sunday 29th June between 00:01 and 04:00 Hrs BST
    </QUOTE>

    --
    (c) John Stockton, near London, UK. Posting with Google.
    Mail: J.R.""""""""@physics.org or (better) via Home Page at
    Web: <URL:http://www.merlyn.demon.co.uk/>
    FAQish topics, acronyms, links, etc.; Date, Delphi, JavaScript, ...
    Dr J R Stockton, Jun 21, 2008
    #7
  8. FAQ server

    dhtml Guest

    Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places? (2008-06-20)

    On Jun 19, 4:00 pm, "FAQ server" <> wrote:

    [snip]

    > ECMAScript Ed. 3.0 (JScript 5.5 [but buggy] and JavaScript 1.5)
    > introduced N.toFixed, the main problem with this is the bugs in
    > JScripts implementation.
    >


    The other problem is that internal representation and handling with
    binary numbers leads to unintuitive results that seem wrong.

    toFixed calls internal ToNumber which calls internal ToInteger, to get
    the exact mathematical value of the number. This is then rounded to a
    value of the Number type.

    This is why Mozilla will give 1.1255.toFixed(3) => 1.125

    javascript:alert(1.1255.toFixed(3))

    javascript:alert(1.1255 ===
    1.1254999999999999449329379785922355949878692626953125)

    Method toFixed is pretty much useless.

    [snip]

    Garrett

    > --
    dhtml, Jun 21, 2008
    #8
  9. dhtml wrote:
    >On Jun 19, 4:00 pm, FAQ server wrote:
    >[snip]
    >> ECMAScript Ed. 3.0 (JScript 5.5 [but buggy] and JavaScript 1.5)
    >> introduced N.toFixed, the main problem with this is the bugs in
    >> JScripts implementation.

    >
    > The other problem is that internal representation and handling
    > with binary numbers leads to unintuitive results that seem wrong.


    The only factor in making binary number handling non-intuitive is that
    most human intuition is heavily influenced by our use habitual of
    decimal numbers. Decimal numbers have exactly the same issues in reality
    (the decimal representation of 1 divided by 3, for example, is going to
    imprecise or impractical), it is just the issues appear in unfamiliar
    locations (with unfamiliar values).

    > toFixed calls internal ToNumber which calls internal ToInteger,
    > to get the exact mathematical value of the number. This is then
    > rounded to a value of the Number type.


    Wouldn't it be a good idea to look at the specification before making
    assertions like this? The algorithm for - toFixed - does not call
    ToNumber at all and it only calls ToInteger on the value that is its
    argument (the "fractionDigits" value).

    > This is why Mozilla will give 1.1255.toFixed(3) => 1.125


    > javascript:alert(1.1255.toFixed(3))


    > javascript:alert(1.1255 ===
    > 1.1254999999999999449329379785922355949878692626953125)


    > Method toFixed is pretty much useless.


    You may be attributing an issue to the wrong part of the process.
    Remember that a numeric literal in source code must be translated into
    an internal number value that is an IEEE double precision floating point
    number, and that not all values that can be represented as a precise
    decimal value can also be precisely represented as an IEEE double
    precision floating point number. If you code the numeric literal
    "1.1255" and it is translated into the nearest available IEEE double
    precision floating point number representation then that happens at the
    compiling stage (or thereabouts) so you shouldn't fault - toFixed - for
    correctly handling that approximate value when it acts at runtime.

    Richard.
    Richard Cornford, Jun 21, 2008
    #9
  10. FAQ server

    dhtml Guest

    Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places? (2008-06-20)

    On Jun 21, 11:10 am, "Richard Cornford" <>
    wrote:
    > dhtml wrote:
    > >On Jun 19, 4:00 pm, FAQ server wrote:


    >
    > > toFixed calls internal ToNumber which calls internal ToInteger,
    > > to get the exact mathematical value of the number. This is then
    > > rounded to a value of the Number type.

    >
    > Wouldn't it be a good idea to look at the specification before making
    > assertions like this? The algorithm for - toFixed - does not call
    > ToNumber at all and it only calls ToInteger on the value that is its
    > argument (the "fractionDigits" value).
    >


    Right.

    toFixed calls ToInteger, which calls ToNumber.

    > Richard.
    dhtml, Jun 22, 2008
    #10
  11. Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places? (2008-06-20)

    yukabuk wrote:
    > You should write this...


    This -- what? --> <http://www.jibbering.com/faq/#FAQ2_3>

    > var numberObj = new Number(6.57634);


    There is no point in creating a Number object there, ...

    > var formattedNumber = numberObj.toFixed(2);


    .... as it is created here implicitly.

    var formattedNumber = (6.57634).toFixed(2);

    or, parametrized:

    var numberValue = 6.57634;
    var formattedNumber = numberValue.toFixed(2);

    However, you have missed this:

    | ECMAScript Ed. 3.0 (JScript 5.5 [but buggy] and JavaScript 1.5)
    | introduced N.toFixed, the main problem with this is the bugs in
    | JScripts implementation.


    PointedEars
    --
    Prototype.js was written by people who don't know javascript for people
    who don't know javascript. People who don't know javascript are not
    the best source of advice on designing systems that use javascript.
    -- Richard Cornford, cljs, <f806at$ail$1$>
    Thomas 'PointedEars' Lahn, Jun 23, 2008
    #11
  12. Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places? (2008-06-20)

    dhtml wrote:
    > On Jun 19, 4:00 pm, "FAQ server" <> wrote:
    >> ECMAScript Ed. 3.0 (JScript 5.5 [but buggy] and JavaScript 1.5)
    >> introduced N.toFixed, the main problem with this is the bugs in
    >> JScripts implementation.

    >
    > [...]
    > javascript:alert(1.1255.toFixed(3))
    >
    > javascript:alert(1.1255 ===
    > 1.1254999999999999449329379785922355949878692626953125)


    You overlook that Number.prototype.toFixed() returns a string value, not a
    number value.

    > Method toFixed is pretty much useless.


    It isn't. If it did not exist, one would always be forced to convert the
    number value to a string and then apply a Regular Expression (or an even
    more inefficient solution) on that string to find the matching digits. One
    can observe what that would mean in the workarounds for that in the FAQ,
    devised in order to accomodate JScript's borken implementation of the
    specified method.

    The built-in implementation is always faster because it is compiled already.


    PointedEars
    --
    realism: HTML 4.01 Strict
    evangelism: XHTML 1.0 Strict
    madness: XHTML 1.1 as application/xhtml+xml
    -- Bjoern Hoehrmann
    Thomas 'PointedEars' Lahn, Jun 23, 2008
    #12
  13. Re: FAQ Topic - How do I convert a Number into a String with exactly 2 decimal places? (2008-06-20)

    In comp.lang.javascript message <>, Mon,
    23 Jun 2008 19:34:44, Thomas 'PointedEars' Lahn <>
    posted:
    >dhtml wrote:


    >> Method toFixed is pretty much useless.

    >
    >It isn't. If it did not exist, one would always be forced to convert the
    >number value to a string and then apply a Regular Expression (or an even
    >more inefficient solution) on that string to find the matching digits. One
    >can observe what that would mean in the workarounds for that in the FAQ,
    >devised in order to accomodate JScript's borken implementation of the
    >specified method.


    That third sentence is factually incorrect. The code in the FAQ was
    devised when method toFixed was not *available*. It was in fact, IIRC,
    devised and put in the FAQ because the code previously in the FAQ was
    unreliable, failing with (for example) the value stored by var x =
    0.07 ; (& YSCIB).

    In addition, consider rounding 999999.999999 and 1000000 to two decimal
    places as your second sentence suggests. A RegExp can easily determine
    the 999999.99 or 1000000; but going from those to 1000000.00 by RegExp
    is not so easy. OTOH, for non-negative values one can use toString(),
    then get the character third after the decimal point, if in 5-9 add
    0.006 to the input and repeat, then use substring to extract the result
    needed, remembering to deal with the special cases. Therefore, your
    second sentence is also unlikely to be true.

    Since toFixed fails on a simple case, it clearly has a defective
    algorithm. Therefore, it would be foolish to use it on any other cases
    that had not been tested, unless the nature of the defect is fully
    understood. First sentence false.


    The algorithm in the FAQ, updated as Randy Webb failed to do, can handle
    with a reasonable result any possible input Number, including NaN
    +Infinity -Infinity null undefined and large, and allows generation if
    required of a fixed number of positions or digits before the decimal
    separator and allows for a choice of leading '+' ' ' or '' for positive
    and zero results. It can easily be simplified is some choices are not
    needed - there's no point in using Math.pow(10, 2) when dealing with
    euros and cents, for example.

    It cannot easily be significantly beaten (Evertjan's been trying for
    years, ISTM); though it can perhaps be approximately equalled.

    --
    (c) John Stockton, nr London, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
    Proper <= 4-line sig. separator as above, a line exactly "-- " (SonOfRFC1036)
    Do not Mail News to me. Before a reply, quote with ">" or "> " (SonOfRFC1036)
    Dr J R Stockton, Jun 24, 2008
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page