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

Discussion in 'Javascript' started by FAQ server, Dec 13, 2006.

  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.

    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 ? '-' : ''; }
    function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }

    Number.prototype.toFixed= new Function('n','return StrS(this,1,n)')

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

    http://msdn.microsoft.com/library/en-us/script56/html/js56jsmthToFixed.asp


    ===
    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://www.jibbering.com/faq/.
    The FAQ workers are a group of volunteers.
    FAQ server, Dec 13, 2006
    #1
    1. Advertising

  2. In comp.lang.javascript message
    <457f428a$0$49209$>, Wed, 13 Dec 2006 00:00:01,
    FAQ server <> wrote:

    > 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 ? '-' : ''; }
    > function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }


    The functions on my site have been updated since that was put in the
    FAQ.



    function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }

    function PrfxTo(S, L, C) { S += ""
    if (C.length>0) while (S.length<L) S = C + S ; return S }

    function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
    while (S.length<L) S = " " + S ; return S }

    function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
    var S = String(Math.round(X*Math.pow(10, N)))
    if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
    S = PrfxTo(S, M+N, '0') ; var T = S.length - N
    return S.substring(0, T) + '.' + S.substring(T) }

    function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }


    Given that some of the function set are intended to give fixed-width
    results, ISTM that Sign should give fixed-width output. When that's
    *not* wanted, removing a bit of the code will be easy.

    --
    (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6
    <URL:http://www.jibbering.com/faq/> A FAQ of news:comp.lang.javascript
    <URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
    <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
    Dr J R Stockton, Dec 13, 2006
    #2
    1. Advertising

  3. FAQ server

    Randy Webb Guest

    Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places?

    Dr J R Stockton said the following on 12/13/2006 5:32 PM:
    > In comp.lang.javascript message
    > <457f428a$0$49209$>, Wed, 13 Dec 2006 00:00:01,
    > FAQ server <> wrote:
    >
    >> 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 ? '-' : ''; }
    >> function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }

    >
    > The functions on my site have been updated since that was put in the FAQ.
    >
    >
    >
    > function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
    >
    > function PrfxTo(S, L, C) { S += ""
    > if (C.length>0) while (S.length<L) S = C + S ; return S }
    >
    > function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
    > while (S.length<L) S = " " + S ; return S }
    >
    > function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
    > var S = String(Math.round(X*Math.pow(10, N)))
    > if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
    > S = PrfxTo(S, M+N, '0') ; var T = S.length - N
    > return S.substring(0, T) + '.' + S.substring(T) }
    >
    > function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }
    >
    >
    > Given that some of the function set are intended to give fixed-width
    > results, ISTM that Sign should give fixed-width output. When that's
    > *not* wanted, removing a bit of the code will be easy.


    All of the code snippets, every one of them, will be reviewed and
    re-written for 10.0 with some documentation and better variable names to
    make them easier for newbes to be able to read and learn from. The FAQ
    isn't geared to experienced users that can decipher code such as that
    above, it is for people who *can't* write code such as that above but
    want to learn from it.

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
    Randy Webb, Dec 14, 2006
    #3
  4. FAQ server

    RobG Guest

    Randy Webb wrote:
    [...]
    > All of the code snippets, every one of them, will be reviewed and
    > re-written for 10.0 with some documentation and better variable names to
    > make them easier for newbes to be able to read and learn from. The FAQ

    [...]
    > is for people who *can't* write code such as that above but
    > want to learn from it.


    Amen to that.

    --
    Rob
    RobG, Dec 14, 2006
    #4
  5. In comp.lang.javascript message <>,
    Wed, 13 Dec 2006 21:35:57, Randy Webb <> wrote:
    >
    >All of the code snippets, every one of them, will be reviewed and re-
    >written for 10.0 with some documentation and better variable names to
    >make them easier for newbes to be able to read and learn from. The FAQ
    >isn't geared to experienced users that can decipher code such as that
    >above, it is for people who *can't* write code such as that above but
    >want to learn from it.


    Where a FAQ entry is headed by a request for an algorithm, a coding
    tutorial is not called for. The Notes are the place for that.

    --
    (c) John Stockton, Surrey, 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, Dec 14, 2006
    #5
  6. FAQ server

    Randy Webb Guest

    Re: FAQ Topic - How do I convert a Number into a String with exactly2 decimal places?

    Dr J R Stockton said the following on 12/14/2006 4:09 PM:
    > In comp.lang.javascript message <>,
    > Wed, 13 Dec 2006 21:35:57, Randy Webb <> wrote:
    >> All of the code snippets, every one of them, will be reviewed and re-
    >> written for 10.0 with some documentation and better variable names to
    >> make them easier for newbes to be able to read and learn from. The FAQ
    >> isn't geared to experienced users that can decipher code such as that
    >> above, it is for people who *can't* write code such as that above but
    >> want to learn from it.

    >
    > Where a FAQ entry is headed by a request for an algorithm, a coding
    > tutorial is not called for. The Notes are the place for that.


    Is there a point to that? I will repeat what I said "All of the code
    snippets, every one of them, will be reviewed and *rewritten for 10.0*.

    --
    Randy
    Chance Favors The Prepared Mind
    comp.lang.javascript FAQ - http://jibbering.com/faq
    Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/
    Randy Webb, Dec 15, 2006
    #6
  7. FAQ server

    krs Guest

    On Dec 13 2006, 2:32 pm, Dr J R Stockton <>
    wrote:
    > FAQ server <> wrote:
    > The functions on my site have been updated since that was put in the
    > FAQ.
    >
    > function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
    >
    > function PrfxTo(S, L, C) { S += ""
    > if (C.length>0) while (S.length<L) S = C + S ; return S }
    >
    > function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
    > while (S.length<L) S = " " + S ; return S }
    >
    > function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
    > var S = String(Math.round(X*Math.pow(10, N)))
    > if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
    > S = PrfxTo(S, M+N, '0') ; var T = S.length - N
    > return S.substring(0, T) + '.' + S.substring(T) }
    >
    > function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }
    >
    > Given that some of the function set are intended to give fixed-width
    > results, ISTM that Sign should give fixed-width output. When that's
    > *not* wanted, removing a bit of the code will be easy.


    can someone else confirm that StrS(1.035,1,2) returns +1.03, instead of
    the correct value of +1.04, on Firefox2 (winxp)?
    -ks
    krs, Jan 16, 2007
    #7
  8. FAQ server

    Evertjan. Guest

    krs wrote on 16 jan 2007 in comp.lang.javascript:
    > On Dec 13 2006, 2:32 pm, Dr J R Stockton
    > <> wrote:
    >> FAQ server <> wrote:
    >> The functions on my site have been updated since that was put in the
    >> FAQ.
    >>
    >> function Sign(X) { return X>0 ? "+" : X<0 ? "-" : " " }
    >>
    >> function PrfxTo(S, L, C) { S += ""
    >> if (C.length>0) while (S.length<L) S = C + S ; return S }
    >>
    >> function SpcsTo(S, L) { S += "" // SpcsTo is a reduction of PrfxTo
    >> while (S.length<L) S = " " + S ; return S }
    >>
    >> function StrU(X, M, N) { // X > -0.5e-N ; to M digits point N digits
    >> var S = String(Math.round(X*Math.pow(10, N)))
    >> if (/\D/.test(S)) return SpcsTo(X, M+N+1) // cannot cope
    >> S = PrfxTo(S, M+N, '0') ; var T = S.length - N
    >> return S.substring(0, T) + '.' + S.substring(T) }
    >>
    >> function StrS(X, M, N) { return Sign(X) + StrU(Math.abs(X), M, N) }
    >>
    >> Given that some of the function set are intended to give fixed-width
    >> results, ISTM that Sign should give fixed-width output. When that's
    >> *not* wanted, removing a bit of the code will be easy.

    >
    > can someone else confirm that StrS(1.035,1,2) returns +1.03, instead
    > of the correct value of +1.04, on Firefox2 (winxp)?


    Both FF2.0.0.1 and IE7 return:

    +1.03

    Why would +1.04 be the correct value?

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jan 16, 2007
    #8
  9. FAQ server

    VK Guest

    Evertjan. wrote:
    > > can someone else confirm that StrS(1.035,1,2) returns +1.03, instead
    > > of the correct value of +1.04, on Firefox2 (winxp)?

    >
    > Both FF2.0.0.1 and IE7 return:
    >
    > +1.03
    >
    > Why would +1.04 be the correct value?


    Because:
    If the number you are rounding is followed by 5, 6, 7, 8, or 9, the
    number has to be rounded up.
    If the number you are rounding is followed by 0, 1, 2, 3, or 4, round
    the number down.

    If some other rounding logic implemented then it must be spelled in the
    code comments.

    In this aspect the native toFixed method follows the common rounding
    rules only on IE (JScript):
    alert(1.035.toFixed(2)); // gives 1.04

    Both FF and Opera show 1.03

    But alert(1.036.toFixed(2)); // show 1.04 on all test browsers

    This way FF and Opera seems implementing an altered rounding rule:

    If the number you are rounding is followed by 6, 7, 8, or 9, the number
    has to be rounded up.
    If the number you are rounding is followed by 0, 1, 2, 3, 4 or 5 round
    the number down.

    Could anyone comment on "the bugs in JScripts implementation" - what is
    exactly meant by that?
    VK, Jan 16, 2007
    #9
  10. FAQ server

    Evertjan. Guest

    FAQ server wrote on 13 dec 2006 in comp.lang.javascript:

    > -----------------------------------------------------------------------
    > 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.
    >
    > 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 ? '-' : ''; }
    > function StrS(X, M, N) { return Sign(X)+StrU(Math.abs(X), M, N) }
    >
    > Number.prototype.toFixed= new Function('n','return StrS(this,1,n)')


    1
    I would prefer to use regex when molding a string into shape:

    <script type='text/javascript'>

    function toFixed2prot(N) {
    var re = new RegExp('(\d{'+N+'})$','')
    return Math.floor(this*Math.pow(10, N)+.5).toString()
    .replace(/(\d{2}$)/,'.$1')
    }

    Number.prototype.toFixed2 = toFixed2prot

    // testing:

    var x = (1.0351).toFixed2(2)
    document.write(x+'<br>')
    var x = (1.035).toFixed2(2)
    document.write(x+'<br>')

    </script>

    The 1.035 problem i will adress in answer to VK

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jan 16, 2007
    #10
  11. FAQ server

    Evertjan. Guest

    VK wrote on 16 jan 2007 in comp.lang.javascript:

    > Evertjan. wrote:
    >> > can someone else confirm that StrS(1.035,1,2) returns +1.03, instead
    >> > of the correct value of +1.04, on Firefox2 (winxp)?

    >>
    >> Both FF2.0.0.1 and IE7 return:
    >>
    >> +1.03
    >>
    >> Why would +1.04 be the correct value?

    >
    > Because:
    > If the number you are rounding is followed by 5, 6, 7, 8, or 9, the
    > number has to be rounded up.
    > If the number you are rounding is followed by 0, 1, 2, 3, or 4, round
    > the number down.
    >


    True, if you define it that way, but a totally wrong argument.

    document.write(1.035 + 0.005);

    will return:

    1.0399999999999998

    so a decimal string like 1.035 seems to be internally represented and
    stored by something a bit less than exactly 1.035.

    When rounding 1.035 so in reality something like 1.0344444444444449,
    would you expect the .toFixed to make an educated guess if
    eiter 1.035 or 1.0344444444444449 was entered, as a string of the source
    code or in a user input, before it was stored?

    No. I for one would not! That is not the job expected from either
    Math.round() or .toFixed().

    I would have those functions to do exactly what is intended and fix the
    problem of the binary conversion [the root of all this evil] sepretately.

    If I needed to have an exact BCD [Binary Coded Decimal] effect,
    I better construct this myself using strings or integer values with
    exponents.

    ====================

    btw:

    That

    document.write(1.035);

    outputs:

    1.035

    is probably an effect of internal rounding by the write()
    and the alert() methods.

    document.write(1.0344444444444449);

    outputs:

    1.034444444444445

    also a rounding effect, it seems.

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jan 16, 2007
    #11
  12. FAQ server

    VK Guest

    Evertjan. wrote:
    > document.write(1.035 + 0.005);
    >
    > will return:
    >
    > 1.0399999999999998
    >
    > so a decimal string like 1.035 seems to be internally represented and
    > stored by something a bit less than exactly 1.035.


    I thought that the proposed proc was for rounding _provided_ numbers,
    not for rounding internal IEEE-754 representations. The whole purpose
    of such algorithm IMO is to make as close as possible i) the strict
    "human" math learned at the school and ii) the approximate PC math. If
    it was not a purpose then this code is misplaced to FAQ - let it be
    moved to some PC-math specific site. For a user seeking for a quick
    answer it is irrelevant that
    US$ calculated price of 10.05 is really internally stored as
    10.05XXXXXXXXXXX. All she wants to know is now to round it without
    monetarily abusing himself or her buyer.

    > When rounding 1.035 so in reality something like 1.0344444444444449,
    > would you expect the .toFixed to make an educated guess if
    > eiter 1.035 or 1.0344444444444449 was entered, as a string of the source
    > code or in a user input, before it was stored?


    Yes, absolutely. Rounding goes from rightmost number to left, with
    0,1,3,4 rounded down and 5,6,7,8,9 rounded up. This is the school/bank
    math and the proc either has to work this way or no use of it.

    >1.0344444444444449
    >1.034444444444445
    >1.03444444444445
    >1.0344444444445
    >1.034444444445
    >1.03444444445
    >1.0344444445
    >1.034444445
    >1.03444445
    >1.0344445
    >1.034445
    >1.03445
    >1.0345
    >1.035


    If some proc cannot outperform this then no use to start the mess on
    the first place, as there are no advantages over the native toFixed()
    method.
    VK, Jan 16, 2007
    #12
  13. FAQ server

    Evertjan. Guest

    VK wrote on 16 jan 2007 in comp.lang.javascript:

    > If some proc cannot outperform this then no use to start the mess on
    > the first place, as there are no advantages over the native toFixed()
    > method.
    >


    Indeed.

    However, I think there where / are some real bugs in .toFixed,
    that have to be fixed. John S. knows such things.

    However having or building a BCD library or using integer cents/pennies
    throughout is always a possibility, when dealing with currency.


    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jan 16, 2007
    #13
  14. VK wrote:
    > Evertjan. wrote:
    >> document.write(1.035 + 0.005);
    >>
    >> will return:
    >>
    >> 1.0399999999999998
    >>
    >> so a decimal string like 1.035 seems to be internally represented
    >> and stored by something a bit less than exactly 1.035.

    >
    > I thought


    If you appreciated for yourself how badly you do that you might be in a
    position to see it as flagging the imminent arrival of another of your
    streams of irrational, irrelevant, ill-considered and worthless
    nonsense. Of course to appreciate your shortcomings you would have to
    not suffer from them.

    > that the proposed proc was for rounding _provided_ numbers,
    > not for rounding internal IEEE-754 representations.


    In a system where all numbers are IEEE floating point numbers it is not
    possible to provide a number in any other form.

    > The whole purpose of such algorithm IMO


    You opinions are, as always, wothless.

    > is to make as close as possible i) the strict "human" math
    > learned at the school


    Where in school? Basic arithmetic classes, introductory statistics, at
    Accountancy school, degree level pure mathematics?

    > and ii) the approximate PC math.


    "And"? And what is "approximate PC math"? You have spouted a great deal
    of twaddle on the subject of number representations in computers over
    the years, which has made it obvious that you hardly understand what
    computers do (or can do) when representing and manipulating numbures.

    > If it was not a purpose then this code is misplaced to
    > FAQ -


    The code in the FAQ is intended to be an alternative to - toFixed - that
    produces the same output as the ECMA 262 specified algorithm for -
    toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5). This allows for
    consistent and predictable behaviour in the face of implementation bugs
    in - toFiexed -, and says nothing as to the appropriateness of the code
    (or of - toFixed -) for any particular task.

    > let it be moved to some PC-math specific site.


    An alternative to - tofixed - is appropriate in a javascript FAQ.

    > For a user seeking for a quick answer it is irrelevant that
    > US$ calculated price of 10.05 is really internally stored as
    > 10.05XXXXXXXXXXX. All she wants to know is now to round it
    > without monetarily abusing himself or her buyer.


    You won't see it (being fundamentally incompetent yourself) but for
    someone attempting to program a system that handles currency to take
    such a cavalier attitude would be inept.

    Because I have worked with them I know that UK share trading systems
    employ 64 bit integer values for all currency values (representing
    multiples of 1/1000 of the currency unit) and only perform integer
    arithmetic on those values. Thus fractional results are truncated, not
    rounded.

    >> When rounding 1.035 so in reality something like 1.0344444444444449,
    >> would you expect the .toFixed to make an educated guess if
    >> eiter 1.035 or 1.0344444444444449 was entered, as a string of the
    >> source code or in a user input, before it was stored?

    >
    > Yes, absolutely.


    Why am I not surprised by that?

    > Rounding goes from rightmost number to left, with
    > 0,1,3,4 rounded down and 5,6,7,8,9 rounded up.


    So you think that there is only one way to round a number?

    > This is the school/bank math


    You have never heard of "Banker's rounding"? And never been educated
    beyond basic arithmetic?

    > and the proc either has to work this way or no use of it.


    That is so often you answer. You encounter something that does not work
    the way your deranged mind expects and so you declare it unusable.

    >>1.0344444444444449
    >>1.034444444444445
    >>1.03444444444445
    >>1.0344444444445
    >>1.034444444445
    >>1.03444444445
    >>1.0344444445
    >>1.034444445
    >>1.03444445
    >>1.0344445
    >>1.034445
    >>1.03445
    >>1.0345
    >>1.035

    >
    > If some proc cannot outperform this then no use to start
    > the mess on the first place, as there are no advantages
    > over the native toFixed() method.


    While the native - toFixed - method produces inconsistent results across
    implementations (and particularly while it is evidently faulty in IE) a
    consistent alternative has many advantages. It may be that what you
    think the code should do is not what it does do, and it may be that it
    is inappropriate for many of the tasks that the inconsiderate would
    apply it to (particularly systems handling currency), but so long as
    what it does do is consistent then its use is appropriate in contexts
    where that is the desired behaviour.

    Richard.
    Richard Cornford, Jan 16, 2007
    #14
  15. FAQ server

    VK Guest

    Richard Cornford wrote:
    <snip irrelevant>
    > The code in the FAQ is intended to be an alternative to - toFixed - that
    > produces the same output as the ECMA 262 specified algorithm for -
    > toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5).


    On the entire Earth there are 2 to many 3 people giving some sh** on
    such subject. This way for FAQ it is irrelevant

    > This allows for
    > consistent and predictable behaviour in the face of implementation bugs
    > in - toFiexed -, and says nothing as to the appropriateness of the code
    > (or of - toFixed -) for any particular task.


    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?
    <snip>

    So I would propose to remove all this irrelevant self-exposure stuff -
    I am taking that JRS is cool in all imaginable aspects of math, but
    this poor FAQ topic is not a place to fall it out.

    Just answer straight to the question with the promised results, so
    6.57634 becomes 6.58
    and - by the way -
    1.035 becomes 1.04

    P.S. Obviously when someone is asking "How do I convert 10.5678 into a
    String with exactly 2 decimal places?"
    she doesn't mean " "How do I convert 10.5678 into 10.56". Even for ones
    with C on calculus the presumed result is 10.57 and not 10.56
    Thus way "how to round?" is always presumed, not "how to truncate". For
    the latter a one-liner code is sufficient. What do IEEE-754 or
    IEEE-754r tell is irrelevant for this FAQ: though anyone is welcome to
    analyze it up to any depth in personal blog and advertise in post
    signatures.
    VK, Jan 16, 2007
    #15
  16. In comp.lang.javascript message <
    glegroups.com>, Mon, 15 Jan 2007 18:08:14, krs <>
    posted:
    >
    >can someone else confirm that StrS(1.035,1,2) returns +1.03, instead of
    >the correct value of +1.04, on Firefox2 (winxp)?


    It should on all systems return +1.03, because
    1.035*100 -> 103.49999999999998
    in IEEE Doubles.

    If you want exact results for currency including halfpennies, you need
    to work in units such that halfpenny quantities are stored exactly.
    Study the second paragraph of the FAQ entry.

    Read IEEE 754, if that's the right number; ECMA 262 should tell you.

    The code in the FAQ is not exactly what I currently use.

    <FAQENTRY>
    The FAQ lacks the word "currency" which might well be a search target.

    IMHO it would be better to omit the first three words of FAQ 4.6, "When
    formatting money" and to create a new 4.x on the general topic of "How
    should currency calculations be done?".

    Points to include : reference to 4.6 & 4.7; distinction between
    accounting (must be exact) and finance (often approximate)<g>[*]</g>;
    converting to new currencies (e.g. DMk to Euro) has exact rules.

    </FAQENTRY>

    For the handling of currency (in Delphi), Google News for "Herbster" and
    for "JohnH".


    Any astrodynamicists or orbital mechanics here?


    [*] "A billion here, a billion there ... it soon adds up to real
    money!".

    --
    (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 MIME.
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links;
    Astro stuff via astron-1.htm, gravity0.htm ; quotings.htm, pascal.htm, etc.
    No Encoding. Quotes before replies. Snip well. Write clearly. Don't Mail News.
    Dr J R Stockton, Jan 16, 2007
    #16
  17. In comp.lang.javascript message <eoiva2$cqn$1$>
    , Tue, 16 Jan 2007 16:42:41, Richard Cornford
    <> posted:

    >In a system where all numbers are IEEE floating point numbers it is not
    >possible to provide a number in any other form.


    One might consider that to be tautological.

    But one can represent numbers in other ways. In strings, for example,
    or in arrays/objects. I have Pascal code for computing with integers of
    up to about 65000 digits (bases 2 to 16), though the largest native size
    is 32-bit.


    >The code in the FAQ is intended to be an alternative to - toFixed - that
    >produces the same output as the ECMA 262 specified algorithm for -
    >toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5). This allows for
    >consistent and predictable behaviour in the face of implementation bugs
    >in - toFiexed -, and says nothing as to the appropriateness of the code
    >(or of - toFixed -) for any particular task.


    Not in the opinion of its author. The code was intended to do the
    required job, including leading zeroes or spaces, as is commonly
    required and generally provided in other languages. It was NOT intended
    to match a (debugged) toFixed.


    >Because I have worked with them I know that UK share trading systems
    >employ 64 bit integer values for all currency values (representing
    >multiples of 1/1000 of the currency unit) and only perform integer
    >arithmetic on those values. Thus fractional results are truncated, not
    >rounded.


    Truncation is not a necessary consequence.
    Delphi "currency" type is scaled by 10,000.

    >>> When rounding 1.035 so in reality something like 1.0344444444444449,
    >>> would you expect the .toFixed to make an educated guess if
    >>> eiter 1.035 or 1.0344444444444449 was entered, as a string of the
    >>> source code or in a user input, before it was stored?



    In such cases, the algorithm should round to, say, an integer of
    micropounds, convert to string, add a decimal point and chop trailing
    zeroes as needed.

    >Why am I not surprised by that?
    >
    >> Rounding goes from rightmost number to left, with
    >> 0,1,3,4 rounded down and 5,6,7,8,9 rounded up.


    Unreasonable anti-2 prejudice.

    --
    (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6
    news:comp.lang.javascript FAQ <URL:http://www.jibbering.com/faq/index.html>.
    <URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
    <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
    Dr J R Stockton, Jan 16, 2007
    #17
  18. Dr J R Stockton wrote:
    > Richard Cornford posted:
    >
    >> In a system where all numbers are IEEE floating point numbers
    >> it is not possible to provide a number in any other form.

    >
    > One might consider that to be tautological.


    It is tautological. VK is the only person who would ever need being told
    (and probably would not see the inevitability even then).

    > But one can represent numbers in other ways.


    Where a number is an entity of a strictly defined type and form being a
    representation of a number is not necessarily being a number. Otherwise,
    yes. Numbers, in the mathematical sense, can be represented in all sorts
    of ways in javascript, and arbitrary mathematical operations applied to
    those representations by javascript code.

    <snip>
    >> The code in the FAQ is intended to be an alternative to - toFixed -
    >> that produces the same output as the ECMA 262 specified algorithm
    >> for - toFixed - (ECMA 262. 3rd Ed. section 15.7.4.5). This allows
    >> for consistent and predictable behaviour in the face of
    >> implementation bugs in - toFiexed -, and says nothing as to the
    >> appropriateness of the code (or of - toFixed -) for any particular
    >> task.

    >
    > Not in the opinion of its author. The code was intended to do the
    > required job, including leading zeroes or spaces, as is commonly
    > required and generally provided in other languages. It was NOT
    > intended to match a (debugged) toFixed.


    Fair enough. I wrote a step-by-step implementation of the - toFixed -
    algorithm to verify bugs in implementations, and it is not a piece of
    code that I would want to use.

    >> Because I have worked with them I know that UK share trading
    >> systems employ 64 bit integer values for all currency values
    >> (representing multiples of 1/1000 of the currency unit) and
    >> only perform integer arithmetic on those values. Thus
    >> fractional results are truncated, not rounded.

    >
    > Truncation is not a necessary consequence.
    > Delphi "currency" type is scaled by 10,000.
    >
    >>>> When rounding 1.035 so in reality something like
    >>>> 1.0344444444444449, would you expect the .toFixed to make an
    >>>> educated guess if
    >>>> eiter 1.035 or 1.0344444444444449 was entered, as a string of the
    >>>> source code or in a user input, before it was stored?

    >
    > In such cases, the algorithm should round to, say, an integer of
    > micropounds, convert to string, add a decimal point and chop
    > trailing zeroes as needed.

    <snip>

    You cannot pay out, or receive, a micropound. Centipouds are as small as
    British money gets ;)

    Richard.
    Richard Cornford, Jan 17, 2007
    #18
  19. In comp.lang.javascript message <Xns98BA88CBE8778eejj99@194.109.133.242>
    , Tue, 16 Jan 2007 12:26:51, Evertjan. <>
    posted:
    >I would prefer to use regex when molding a string into shape:


    Agreed.

    Here's a rough first try, undertested, unsigned, PrfxTo cf FAQ 4.6
    Stretch :-

    function Hasty1(X) { var Y, Z, Q=0 // Trunc; Q=5 to Round. Bankers???
    Y = String(Math.round(X*1000)+Q)
    Z = PrfxTo(Y, 4, "0").replace(/(\d\d)(\d)$/, ".$1")
    return Z }


    OTOH, for a variable number of decimal places, substr/substring may be
    easier than RegExp.

    --
    (c) John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v6.05 IE 6
    news:comp.lang.javascript FAQ <URL:http://www.jibbering.com/faq/index.html>.
    <URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
    <URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
    Dr J R Stockton, Jan 17, 2007
    #19
  20. FAQ server

    Evertjan. Guest

    Dr J R Stockton wrote on 17 jan 2007 in comp.lang.javascript:

    > In comp.lang.javascript message <Xns98BA88CBE8778eejj99@

    194.109.133.242>
    > , Tue, 16 Jan 2007 12:26:51, Evertjan. <>
    > posted:
    >>I would prefer to use regex when molding a string into shape:

    >
    > Agreed.
    >
    > Here's a rough first try, undertested, unsigned, PrfxTo cf FAQ 4.6
    > Stretch :-
    >
    > function Hasty1(X) { var Y, Z, Q=0 // Trunc; Q=5 to Round.
    > Y = String(Math.round(X*1000)+Q)


    Y = String(Math.floor(X*1000+Q))

    > Z = PrfxTo(Y, 4, "0").replace(/(\d\d)(\d)$/, ".$1")


    You would not need the second ()

    Z = ... .replace(/(\d\d)\d$/, ".$1")

    > return Z }


    Would it be an idea if one defines x.xx5 as always round up,
    thinking for the moment only of positive values,
    to add a tiny bit:

    round: Q = 5.0001

    floor: Q = 0.0001

    Is it true that the binary converion problem always gives result
    differences that are slightly to low, [or correct of course]?

    > Bankers???


    Personally, I do not need or want this silly idea of toggled rounding.
    It is not important in scientific measurement, where an exact value is
    never obtained anyway, only with currency, perhaps, in the amount
    nonvirtual mortals only dream of.

    So it cannot be that important in clientside(!) javascript.

    > OTOH, for a variable number of decimal places, substr/substring may be
    > easier than RegExp.


    var Q = .0001 //5.0001
    var NN = 1; for var i=0;i<N;i++) NN*=10
    var Y = String(Math.floor(X*NN+Q))
    ..... .replace(new RegExp("(\\d{"+N+"})\\d$"), ".$1")
    [N>0]

    or:

    var NN='1000000000000'.substr(0,N+1)

    --
    Evertjan.
    The Netherlands.
    (Please change the x'es to dots in my emailaddress)
    Evertjan., Jan 17, 2007
    #20
    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.
Similar Threads
  1. FAQ server
    Replies:
    6
    Views:
    166
    Dr J R Stockton
    Nov 3, 2006
  2. FAQ server
    Replies:
    28
    Views:
    301
    Randy Webb
    Feb 23, 2007
  3. FAQ server
    Replies:
    1
    Views:
    146
    Dr J R Stockton
    Apr 15, 2007
  4. FAQ server
    Replies:
    0
    Views:
    104
    FAQ server
    Jun 14, 2007
  5. FAQ server
    Replies:
    0
    Views:
    112
    FAQ server
    Aug 15, 2007
Loading...

Share This Page