Help ! Shopping Cart Problem

Discussion in 'Javascript' started by Phil McKraken, Oct 29, 2005.

  1. I am having a problem putting together a shopping cart with the below
    script. Everything displays fine, adds totals fine, and works perfect
    EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
    $9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
    whatever you add. That is the only price in these samples that is
    doing that. All the others display properly. If you change the 9.95 to
    ANY other number it displays correct. If you put 9.95 in any other
    position (Item number 1 instead of 5 etc. it does the same thing)

    Any ideas ? I am completely stumped. Please Help
    TIA

    (This is the entire html page you can paste it and view in a browser
    to see the problem with the 9.95 item.)

    <html><head>

    <script language="JavaScript">
    <!-- hide contents from old browsers

    var Cost, Grand_Total;

    function tally()
    {
    Cost = 0;
    if (document.orderform.Item1.checked) { Cost = Cost + 119.95;
    }
    if (document.orderform.Item2.checked) { Cost = Cost + 75.00; }
    if (document.orderform.Item3.checked) { Cost = Cost + 14.95; }
    if (document.orderform.Item4.checked) { Cost = Cost + 50.00; }
    if (document.orderform.Item5.checked) { Cost = Cost + 9.95; }
    if (document.orderform.Item6.checked) { Cost = Cost + 4.95; }
    if (document.orderform.Item7.checked) { Cost = Cost + 50.00; }
    if (document.orderform.Item8.checked) { Cost = Cost + 7.95; }
    if (document.orderform.Item9.checked) { Cost = Cost + 1.00; }

    Cost = dollar(Cost);
    Grand_Total = parseFloat(Cost)
    Grand_Total = dollar(Grand_Total);

    document.orderform.GrandTotal.value = "$" + Grand_Total;
    }

    function dollar (amount)
    {
    amount = parseInt(amount * 100);
    amount = parseFloat(amount/100);
    if (((amount) == Math.floor(amount)) && ((amount - Math.floor
    (amount)) == 0))
    {
    amount = amount + ".00"
    return amount;
    }
    if ( ((amount * 10) - Math.floor(amount * 10)) == 0)
    {
    amount = amount + "0";
    return amount;
    }
    if ( ((amount * 100) - Math.floor(amount * 100)) == 0)
    {
    amount = amount;
    return amount;
    }
    return amount;
    }

    //-->
    </script>
    </head>
    <body><center>

    <form method="post" name="orderform" action="mailto:"
    enctype="text/plain">
    <table bgcolor="#EFEFEF" border="0" cellspacing="0"
    cellpadding="3"><font face="verdana" size="1" color="#000000"><b>
    <tr><td valign="top"><font face="verdana" size="2"
    color="#000000"><b>
    <p><input name="Item1" value="AcceleratedHighSpeedAnnual"
    onclick="tally()" type="checkbox">Accelerated Dial-Up Internet Access
    1 Year Pre-Pay ($119.95)
    </p><p><input name="Item2" value="Item2_chosen" onclick="tally()"
    type="checkbox"> Accelerated Dial Up Internet Access Semi-Annual
    Pre-Pay ($75.00)
    </p><p><input name="Item3" value="Item3_chosen" onclick="tally()"
    type="checkbox"> Accelerated Dial Up Internet Access Monthly Billing
    ($14.95)
    </p><p><input name="Item4" value="Item4_chosen" onclick="tally()"
    type="checkbox"> Regular Dial Up Internet Access Semi-Annual Billing
    ($50.00)
    </p><p><input name="Item5" value="Item5_chosen" onclick="tally()"
    type="checkbox"> Regular Dial Up Internet Access Monthly Billing
    ($9.95)
    </p></td><td valign="top"><font face="verdana" size="2"
    color="#000000"><b>
    </p><p><input name="Item6" value="Item6_chosen" onclick="tally()"
    type="checkbox"> Add 3 Email Monthly Billing ($4.95)
    </p><p><input name="Item7" value="Item7_chosen" onclick="tally()"
    type="checkbox"> Add 3 Email 1 Year Pre-Pay ($50.00)
    </p><p><input name="Item8" value="Item8_chosen" onclick="tally()"
    type="checkbox"> 10 Email Only Monthly Billing Only (7.95)
    </p><p><input name="Item9" value="Item9_chosen" onclick="tally()"
    type="checkbox"> Mail Invoice for Payment by Check ($1.00)
    <br><br><font color="red">Total Due: <input name="GrandTotal"
    value="$0" size="8" type="text"></font>
    </p></td></tr></table><br><br>
    <center><input value="Send Order" type="submit"><input value="Reset
    Order" type="reset"></center>
    </form>
    </body></html>
    Phil McKraken, Oct 29, 2005
    #1
    1. Advertising

  2. Phil McKraken

    RobG Guest

    Phil McKraken wrote:
    > I am having a problem putting together a shopping cart with the below
    > script. Everything displays fine, adds totals fine, and works perfect
    > EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
    > $9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
    > whatever you add. That is the only price in these samples that is
    > doing that. All the others display properly. If you change the 9.95 to
    > ANY other number it displays correct. If you put 9.95 in any other
    > position (Item number 1 instead of 5 etc. it does the same thing)
    >
    > Any ideas ? I am completely stumped. Please Help


    The problem is your dollar() function, here is a link to some 'to money'
    conversion stuff:

    <URL:http://www.merlyn.demon.co.uk/js-maths.htm#Money>

    Or search the group for money conversion functions, I'm sure there are a
    couple of good ones that have been posted. There is an extensive thread
    here:

    <URL:http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/9e52a20003237010/df3038f5a0934436?tvc=1&q=convert+to+money&hl=en#df3038f5a0934436>


    Converting strings to numbers and back using multiplication may result
    in a rounded value that is not what you started with - 9.95 being a
    'magic' number for your dollar function.

    Use string manipulation for formatting numbers if you want to ensure
    that they don't get modified.

    [...]

    --
    Rob
    RobG, Oct 29, 2005
    #2
    1. Advertising


  3. >The problem is your dollar() function, here is a link to some 'to money'
    >conversion stuff:


    I tried the links you posted but, :) no luck. I am sure I am just
    doing it wrong. I got this sample from one of those javascript web
    repositories and I am not competent to change it to make it work. I am
    still learning and am not really a js writer, only a "cut n paste"
    trial & error modifier of what's there already.

    Can someone tell me what to do to fix this a little more specifically.

    Thanks for the responses. I really appreciate it. This is the way you
    learn I guess.

    When I tried the links, I screwed it up so bad it doesn't work at all
    now. (Yes I have a backup that works the same as the original with the
    "9.95" problem)

    Thanks again.
    Phil McKraken, Oct 29, 2005
    #3
  4. Phil McKraken

    Randy Webb Guest

    Phil McKraken said the following on 10/29/2005 12:03 PM:
    >>The problem is your dollar() function, here is a link to some 'to money'
    >>conversion stuff:

    >
    >
    > I tried the links you posted but, :) no luck. I am sure I am just
    > doing it wrong. I got this sample from one of those javascript web
    > repositories and I am not competent to change it to make it work. I am
    > still learning and am not really a js writer, only a "cut n paste"
    > trial & error modifier of what's there already.
    >
    > Can someone tell me what to do to fix this a little more specifically.


    You are trying to round by multiplying by 100 and then dividing by 100.
    That introduces the error you see because computers cannot represent
    9.95 exactly in Base 2. So you get the error.

    The way around that error is to convert your Number to a whole number,
    do your calculations, and then add the decimal back with *String
    Operations*. Meaning, you do not divide by 100, you convert it to a
    String and then add the decimal.

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
    Randy Webb, Oct 29, 2005
    #4
  5. Phil McKraken

    Lee Guest

    Phil McKraken said:
    >
    >I am having a problem putting together a shopping cart with the below
    >script. Everything displays fine, adds totals fine, and works perfect
    >EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
    >$9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
    >whatever you add. That is the only price in these samples that is
    >doing that. All the others display properly. If you change the 9.95 to
    >ANY other number it displays correct. If you put 9.95 in any other
    >position (Item number 1 instead of 5 etc. it does the same thing)
    >
    > Any ideas ? I am completely stumped. Please Help


    That's really just horrible code, and should be thrown away,
    but the simplest fix to your problem is to remove the line
    indicated below. Every time you call that ridiculous dollar()
    function you introduce more error, so don't call it without
    any reason. There's also no reason to use either parseFloat()
    or parseInt() in this code, but at least they're not causing
    the problem.


    >function tally()
    > {
    > Cost = 0;
    > if (document.orderform.Item1.checked) { Cost = Cost + 119.95;
    >}
    > if (document.orderform.Item2.checked) { Cost = Cost + 75.00; }
    > if (document.orderform.Item3.checked) { Cost = Cost + 14.95; }
    > if (document.orderform.Item4.checked) { Cost = Cost + 50.00; }
    > if (document.orderform.Item5.checked) { Cost = Cost + 9.95; }
    > if (document.orderform.Item6.checked) { Cost = Cost + 4.95; }
    > if (document.orderform.Item7.checked) { Cost = Cost + 50.00; }
    > if (document.orderform.Item8.checked) { Cost = Cost + 7.95; }
    > if (document.orderform.Item9.checked) { Cost = Cost + 1.00; }
    >
    > Cost = dollar(Cost); // REMOVE THIS LINE
    > Grand_Total = parseFloat(Cost)
    > Grand_Total = dollar(Grand_Total);
    >
    > document.orderform.GrandTotal.value = "$" + Grand_Total;
    > }
    >
    Lee, Oct 29, 2005
    #5
  6. On 29 Oct 2005 11:05:04 -0700, Lee <> wrote:

    >That's really just horrible code, and should be thrown away,
    >but the simplest fix to your problem is to remove the line
    >indicated below. Every time you call that ridiculous dollar()
    >function you introduce more error, so don't call it without
    >any reason. There's also no reason to use either parseFloat()
    >or parseInt() in this code, but at least they're not causing
    >the problem.


    I appreciate the help and the sentiment regarding the code. I guess I
    will have to find another one. I DID remove the line you suggested but
    ALSO had to remove the "dollar" reference in the 2nd line down, with
    Grand_Total.

    Doing that caused the 9.95 and other **.95 items to display and add
    ok. BUT, when you add ANY **.95 item to anything else (resulting in a
    total that ends in "0" it drops off the "0".

    I'm just not understanding enough of js yet to trouble shoot this.

    Anyone know a better one ?

    Thanks
    Phil McKraken, Oct 29, 2005
    #6
  7. Help ! Shopping Cart Problem

    JRS: In article <43637d2f$0$21705$5a62ac22@per-qv1-newsreader-
    01.iinet.net.au>, dated Sat, 29 Oct 2005 23:44:47, seen in
    news:comp.lang.javascript, RobG <> posted :
    >
    >The problem is your dollar() function, here is a link to some 'to money'
    >conversion stuff:
    >
    > <URL:http://www.merlyn.demon.co.uk/js-maths.htm#Money>


    <URL:http://www.merlyn.demon.co.uk/js-round.htm> is a more general
    reference; and then there's the code in the FAQ.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
    The Big-8 newsgroup management is attempting to legitimise its questionable
    practices while retaining its elitist hegemony. Read <URL:news:news.groups>.
    Dr John Stockton, Oct 29, 2005
    #7
  8. Help ! Shopping Cart Problem

    JRS: In article <>, dated
    Sat, 29 Oct 2005 12:36:50, seen in news:comp.lang.javascript, Phil
    McKraken <> posted :
    >I am having a problem putting together a shopping cart with the below
    >script. Everything displays fine, adds totals fine, and works perfect
    >EXCEPT if you choose the 9.95 item #5 BY ITSELF the total displayed is
    >$9.94 ! If you add ANYTHING else the total is correct, 9.95 plus
    >whatever you add. That is the only price in these samples that is
    >doing that. All the others display properly. If you change the 9.95 to
    >ANY other number it displays correct.


    You have tried all other numbers? For me, 19.65 gives 19.64.

    > If you put 9.95 in any other
    >position (Item number 1 instead of 5 etc. it does the same thing)
    >
    > Any ideas ? I am completely stumped. Please Help


    Read the newsgroup FAQ and what it cites.

    Your conversion method, as well as being wrong, appears unnecessarily
    large and slow. Delete your function "dollar"; euthanasia is the
    kindest treatment for it.

    Most scripts in Web repositories are trash; many are also bloatware.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
    <URL:http://www.jibbering.com/faq/> JL/RC: 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 John Stockton, Oct 29, 2005
    #8
  9. Phil McKraken

    RobG Guest

    Phil McKraken wrote:
    >>The problem is your dollar() function, here is a link to some 'to money'
    >>conversion stuff:

    >
    >
    > I tried the links you posted but, :) no luck. I am sure I am just
    > doing it wrong. I got this sample from one of those javascript web
    > repositories and I am not competent to change it to make it work. I am
    > still learning and am not really a js writer, only a "cut n paste"
    > trial & error modifier of what's there already.
    >
    > Can someone tell me what to do to fix this a little more specifically.


    You really need to understand what the functions are doing and how they
    work, else you will get errors like you have now. I hope you are
    validating everything back at the server and only using the shopping
    cart for advice to customers.

    Anyhow, here's a couple of functions that may suit. They do no
    validation at all and expect you to pass them suitable input. The first
    expects to get dollars and never more than two decimal places, the
    second expects integer cents.



    <html><head><title>Play</title>

    <script type="text/javascript">

    // This function expects to get dollars as either an integer
    // or a float but never more than 2 decimal places
    function toDollars(amt)
    {
    if (0 == amt) return '0.00';
    amt += ''; // Convert amt to string
    amt = amt.split('.');
    if (1 == amt.length) amt[1]='00';
    if (0 == amt[1].length) amt[1] += '00';
    if (1 == amt[1].length) amt[1] += '0';
    return amt.join('.');
    }

    // This function expects to get only integer cents
    function centsToDollars(amt)
    {
    amt += ''; // Convert amt to string
    if (1 == amt.length) return '0.0'+ amt;
    if (2 == amt.length) return '0.'+ amt;
    var dollars = amt.substring(0,amt.length-2);
    var cents = amt.substring(amt.length-2);
    return dollars + '.' + cents;
    }

    </script>
    </head><body>
    Play with toDollars<br>
    <input type="text" onblur="
    this.value = toDollars(this.value);
    "><br>
    Play with centsToDollars<br>
    <input type="text" onblur="
    this.value = centsToDollars(this.value);
    ">

    </body></html>


    [...]

    --
    Rob
    RobG, Oct 30, 2005
    #9
  10. Help ! Shopping Cart Problem

    JRS: In article <>, dated Sat, 29 Oct
    2005 13:45:09, seen in news:comp.lang.javascript, Randy Webb
    <> posted :
    >
    >You are trying to round by multiplying by 100 and then dividing by 100.
    >That introduces the error you see because computers cannot represent
    >9.95 exactly in Base 2. So you get the error.


    Non sequitur.

    If the representation of 9.95, while not exact, had sufficient zeroes at
    the end of the mantissa, then the multiplication would be exact, and the
    division would be exact and would give the original value. There,
    "sufficient zeroes" is a sufficient, but probably not entirely
    necessary, condition.

    If 9.95 being represented inexactly were the only criterion, then ISTM
    that one would expect more wrong results than the OP's code actually
    gives.


    The real problem is that the OP's type of method effectively truncates
    to cents using an inexact input; the input must be rounded to exact
    cents, which has to be done into a representation where all such values
    can be rendered exactly.

    The ordinary conversions of a general Number to a String do that
    rounding, as does the obvious one of the conversions to an integer Cent
    number.

    Note that one should always multiply or divide by 100 in preference to
    dividing or multiplying by 0.01, since 100 is represented exactly but
    0.01 is not.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
    The Big-8 newsgroup management is attempting to legitimise its questionable
    practices while retaining its elitist hegemony. Read <URL:news:news.groups>.
    Dr John Stockton, Oct 30, 2005
    #10
  11. Help ! Shopping Cart Problem

    JRS: In article <>, dated
    Sat, 29 Oct 2005 19:37:51, seen in news:comp.lang.javascript, Phil
    McKraken <> posted :
    >On 29 Oct 2005 11:05:04 -0700, Lee <> wrote:
    >
    >>That's really just horrible code, and should be thrown away,
    >>but the simplest fix to your problem is to remove the line
    >>indicated below. Every time you call that ridiculous dollar()
    >>function you introduce more error, so don't call it without
    >>any reason. There's also no reason to use either parseFloat()
    >>or parseInt() in this code, but at least they're not causing
    >>the problem.

    >
    >I appreciate the help and the sentiment regarding the code. I guess I
    >will have to find another one. I DID remove the line you suggested but
    >ALSO had to remove the "dollar" reference in the 2nd line down, with
    >Grand_Total.
    >
    >Doing that caused the 9.95 and other **.95 items to display and add
    >ok. BUT, when you add ANY **.95 item to anything else (resulting in a
    >total that ends in "0" it drops off the "0".
    >
    >I'm just not understanding enough of js yet to trouble shoot this.


    Your lack of understanding is more fundamental. You do not understand
    the properties of the IEEE Double type. You probably do not even
    understand that you need to understand that.


    >Anyone know a better one ?


    Read the newsgroup FAQ.

    It should be obvious enough to you that conversion of a currency
    variable to a currency string is quite commonly needed, and, therefore,
    that if the language does not provide, in all versions, an obvious and
    reliable way of doing it, then the information needed can very probably
    be found in or via a newsgroup FAQ.

    No-one with any sense will bother to copy out the version in the
    newsgroup FAQ when the whole purpose of having a newsgroup FAQ is to
    obviate the repeated asking of common questions.

    Remember that at least 90% of the script on the web, especially that in
    repositories and libraries, is trash (script in actual use tends to get
    debugged). Read the newsgroup FAQ.

    Don't forget to read the newsgroup FAQ.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
    <URL:http://www.jibbering.com/faq/> JL/RC: 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 John Stockton, Oct 30, 2005
    #11
  12. Help ! Shopping Cart Problem

    JRS: In article <4364ad27$0$20422$5a62ac22@per-qv1-newsreader-
    01.iinet.net.au>, dated Sun, 30 Oct 2005 21:21:45, seen in
    news:comp.lang.javascript, RobG <> posted :

    >function toDollars(amt)
    >{
    > if (0 == amt) return '0.00';
    > amt += ''; // Convert amt to string
    > amt = amt.split('.');
    > if (1 == amt.length) amt[1]='00';
    > if (0 == amt[1].length) amt[1] += '00';
    > if (1 == amt[1].length) amt[1] += '0';
    > return amt.join('.');
    >}
    >


    Or

    function toDollars(amt) {
    if (0 == amt) return '0.00'
    amt = String(amt).split('.')
    if (1 == amt.length) amt[1] = "0"
    if (1 == amt[1].length) amt[1] += '0'
    return amt.join('.') }

    But that still requires, for \d+\.\d\d, String(amt) to show two decimal
    places. Note : 0.06 + 0.01 -> 0.06999999999999999

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
    The Big-8 newsgroup management is attempting to legitimise its questionable
    practices while retaining its elitist hegemony. Read <URL:news:news.groups>.
    Dr John Stockton, Oct 30, 2005
    #12
  13. Phil McKraken

    Randy Webb Guest

    Re: Help ! Shopping Cart Problem

    Dr John Stockton posted the following on 10/30/2005 2:10 PM:

    <snip>

    Why does your News Agent keep changing the Subject line, or, are you
    doing that manually?

    --
    Randy
    comp.lang.javascript FAQ - http://jibbering.com/faq & newsgroup weekly
    Randy Webb, Oct 30, 2005
    #13
  14. Phil McKraken

    RobG Guest

    Re: Help ! Shopping Cart Problem

    Dr John Stockton wrote:
    > JRS: In article <4364ad27$0$20422$5a62ac22@per-qv1-newsreader-
    > 01.iinet.net.au>, dated Sun, 30 Oct 2005 21:21:45, seen in
    > news:comp.lang.javascript, RobG <> posted :
    >
    >> function toDollars(amt)
    >> {
    >> if (0 == amt) return '0.00';
    >> amt += ''; // Convert amt to string
    >> amt = amt.split('.');
    >> if (1 == amt.length) amt[1]='00';
    >> if (0 == amt[1].length) amt[1] += '00';
    >> if (1 == amt[1].length) amt[1] += '0';
    >> return amt.join('.');
    >> }
    >>

    >
    > Or
    >
    > function toDollars(amt) {
    > if (0 == amt) return '0.00'
    > amt = String(amt).split('.')
    > if (1 == amt.length) amt[1] = "0"
    > if (1 == amt[1].length) amt[1] += '0'
    > return amt.join('.') }
    >
    > But that still requires, for \d+\.\d\d, String(amt) to show two decimal
    > places. Note : 0.06 + 0.01 -> 0.06999999999999999
    >


    Yes, maybe expecting properly formatted strings in the first place was
    unreasonable of me in the OP's case.

    I suppose I was searching for a function that fulfills the requirement
    of formating numbers for decimal currency with 2 places and that isn't
    too daunting.

    FAQ #4.6 has the heading "How do I convert a Number into a String with
    exactly 2 decimal places?" but the advice provided seems out of place
    with the heading.

    The suggested solution seems much more appropriate to FAQ #4.7, I think
    its complexity results in it either being put in the too-hard basket or
    incorrectly applied (e.g. the OPs comments in this thread).

    Perhaps FAQ #4.6 would be better if it provided a function that returns
    exactly two decimal places.

    The following should be suitable:

    function twoDecimals(n)
    {
    var sign = (n<0)? '-':'';
    n = Math.round(Math.abs(n)*100) + '';
    while (n.length<3) n = '0'+n;
    var len = n.length-2;
    return sign + n.substring(0,len)+'.'+n.substring(len);
    }

    Noting that 'n' must be either an integer or floating point number.



    While investigating the above, I noticed that Firefox has some
    unexpected (buggy?) behaviour indicated below.

    toFixed() is the native method and toFixedMod() is from FAQ#4.6:

    var num = 2/0.3;

    i (places) num.toFixed(i) num.toFixedMod(i)
    13 6.6666666666667 6.6666666666667
    14 6.66666666666667 6.66666666666667
    15 6.666666666666667 6.666666666666668
    16 6.6666666666666670 6.6666666666666670
    17 6.66666666666666696 6.66666666666666800
    18 6.666666666666666963 6.666666666666667000
    19 6.6666666666666669627 6.6666666666666670000
    20 6.66666666666666696273 6.66666666666666800000
    21 6.666666666666666962726 6.666666666666667
    22 6.6666666666666669627261 6.666666666666667
    23 6.66666666666666696272614 6.666666666666667
    24 6.666666666666666962726140 6.666666666666667

    Interesting results for IE:
    14 6.66666666666667 6.66666666666667
    15 6.666666666666667 6.666666666666668
    16 6.6666666666666670 6.6666666666666670
    17 6.66666666666666700 6.66666666666666700
    18 6.666666666666667000 6.666666666666667000
    19 6.6666666666666670000 6.6666666666666670000
    20 6.66666666666666700000 6.66666666666666700000
    21 [object Error] 6.666666666666667
    22 [object Error] 6.666666666666667
    ...

    The modified toFixed suggested in the FAQ seems to provide limited
    benefit to IE or Firefox, it may be better to offer it only for browsers
    without a toFixed method and to suggest that floating point arithmetic
    beyond 14(?) decimal places not be attempted with native JavaScript
    functions.

    I would think that anyone who was doing that and expecting accurate
    results would thoroughly investigate all the issues anyway.


    The test used to generate the above results is provided below.
    Try..catch is used because IE fails silently with toFixed(i) if i>20 :

    <script type="text/javascript">

    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;
    var 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.toFixedMod =
    new Function('n','return StrS(this,1,n)')

    </script>

    <table border="1">
    <tr><td colspan="3">
    <script type="text/javascript">
    var x = 2/0.3;
    document.write(x);
    </script>
    </td>
    </tr>
    <tr>
    <th>i (places)</th>
    <th>num.toFixed(i)</th>
    <th>num.toFixedMod(i)</th>
    </tr>
    <script type="text/javascript">

    var tf, s='';
    for (var i=10; i<25; ++i){

    try {
    tf = x.toFixed(i);
    } catch (e) {tf = e;}

    s += '<tr><td>' + i + '</td><td>'
    + tf + '</td><td>'
    + x.toFixedMod(i) + '</td></tr>';
    }
    document.write(s);
    </script>

    </table>




    --
    Rob
    RobG, Oct 31, 2005
    #14
  15. Phil McKraken

    RobG Guest

    Re: Help ! Shopping Cart Problem

    RobG wrote:
    [...]
    > While investigating the above, I noticed that Firefox has some
    > unexpected (buggy?) behaviour indicated below.


    Further testing in Safari 1.0.3 showed that is has no native toFixed
    method and the FAQ's suggested routine fails beyond 8 decimal places:

    i FAQ toFixed(i)
    7 6.6666667
    8 6.66666667
    9 2.147483647
    10 0.2147483647
    11 0.02147483647
    12 0.002147483647

    Safari 1.3 showed results the same as Windows Firefox, as did the Mac
    version of Firefox 1.0.7.

    IE 5.2 (Mac) behaved the same as the Windows version, but again it has
    no native toFixed method.

    iCab (3.0 Beta) gives different results yet again, though it seems the
    most consistent with the FAQ toFixed and shows a 14 place limit too:

    i native toFixed FAQ toFixed
    11 6.66666666667 6.66666666667
    12 6.666666666667 6.666666666667
    13 6.6666666666667 6.6666666666667
    14 6.66666666666667 6.66666666666667
    15 6.666666666666667 6.66666666666667
    16 6.6666666666666670 6.66666666666667
    17 6.66666666666666696 6.66666666666667
    18 6.666666666666666963 6.66666666666667
    19 6.6666666666666669627 6.66666666666667
    20 6.66666666666666696273 6.66666666666667
    21 RangeError 6.66666666666667
    22 RangeError 6.66666666666667


    And finally Opera 8.5 (Mac):

    i native toFixed FAQ toFixed
    14 6.66666666666667 6.66666666666667
    15 6.666666666666667 6.666666666666668
    16 6.6666666666666670 6.6666666666666670
    17 6.66666666666666696 6.66666666666666800
    18 6.666666666666666963 6.666666666666667000
    19 6.6666666666666669627 6.6666666666666670000
    20 6.66666666666666696273 6.66666666666666800000
    21 [Error: name: RangeError ...] 6.666666666666667
    22 [Error: name: RangeError ...] 6.666666666666667


    It would seem that the toFixed suggested in the FAQ does not take
    enough consideration of the shortcomings or vagaries of floating point
    arithmetic in various browsers.

    At least that should be noted, along with either a test harness to
    determine the function's usefulness in various situations or a brief
    description of what should be tested before using it.


    [...]


    --
    Rob
    RobG, Oct 31, 2005
    #15
  16. Re: Help ! Shopping Cart Problem

    JRS: In article <>, dated
    Sun, 30 Oct 2005 18:53:31, seen in news:comp.lang.javascript, Randy Webb
    <> posted :
    >Dr John Stockton posted the following on 10/30/2005 2:10 PM:
    >
    ><snip>
    >
    >Why does your News Agent keep changing the Subject line, or, are you
    >doing that manually?


    AIUI, it matches the Subject line, independently of case or spacing,
    with the oldest possible known Subject line; and then uses that oldest
    version, which may well be stored with spacing normalised, adding "Re: "
    at the front if one is not already there. Or something like that.

    It stores articles in an encrypted database, and, for speed of
    searching, different parts may well be stored in different places.

    Re: "Why?", for that you need to ask in news:demon.ip.support.turnpike,
    where the originator and other experts are still to be found.

    It may be concerned with threading-by-subject and the desire to ignore
    inconsequential variations, and/or with a desire to protect against
    "trap" Subjects such as
    0.06+0.01!=0.07? vulgarity!

    I presume that the practice was allowed by the RFCs extant at the time
    of release, as the product is notorious for standards-compliance. The
    authors may well have taken advantage of a possibility that few realised
    was available.

    You should see no change this time, AFAICS.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
    Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
    The Big-8 newsgroup management is attempting to legitimise its questionable
    practices while retaining its elitist hegemony. Read <URL:news:news.groups>.
    Dr John Stockton, Oct 31, 2005
    #16
  17. Re: Help ! Shopping Cart Problem

    JRS: In article <iPj9f.1237$>, dated Mon, 31
    Oct 2005 07:35:42, seen in news:comp.lang.javascript, RobG
    <> posted :


    >FAQ #4.6 has the heading "How do I convert a Number into a String with
    >exactly 2 decimal places?" but the advice provided seems out of place
    >with the heading.
    >
    >The suggested solution seems much more appropriate to FAQ #4.7, I think
    >its complexity results in it either being put in the too-hard basket or
    >incorrectly applied (e.g. the OPs comments in this thread).


    ISTM that the FAQ, if re-written, could have the Section numbers (1..5)
    changed, do that the present Section 4 could be split and re-arranged
    without confusion between, for example, the old and the new Section 4.8.
    Then I'd put the present 4.6 before the present 4.5.


    >Perhaps FAQ #4.6 would be better if it provided a function that returns
    >exactly two decimal places.
    >
    >The following should be suitable:
    >
    >function twoDecimals(n)
    >{
    > var sign = (n<0)? '-':'';
    > n = Math.round(Math.abs(n)*100) + '';
    > while (n.length<3) n = '0'+n;
    > var len = n.length-2;
    > return sign + n.substring(0,len)+'.'+n.substring(len);
    >}
    >
    >Noting that 'n' must be either an integer or floating point number.


    A Number or numeric expression is expected (NaN & Infinity included),
    but the version of StrU which I currently use is happy with a Boolean or
    a Date Object, and passes an Array unchanged, and tolerates Strings,
    Functions, and vars of value undefined.

    Code in a recent article by Evertjan supports calculation in Cents with
    output in Euros, and a (<G>my</G>) version should be included in a
    <FAQENTRY> explicitly on why it's better to calculate in Cents.



    >While investigating the above, I noticed that Firefox has some
    >unexpected (buggy?) behaviour indicated below.



    >The modified toFixed suggested in the FAQ seems to provide limited
    >benefit to IE or Firefox, it may be better to offer it only for browsers
    >without a toFixed method


    As in my js-round.htm and include1.js. But a Reliable Witness has said
    that the toFixed supplied by MS is buggy. I'd recommend not using
    toFixed at all; but, if you want something like it, implement say ToFixt
    - the name is reminiscent of toFixed but does not imply the same bugs.


    > and to suggest that floating point arithmetic
    >beyond 14(?) decimal places not be attempted with native JavaScript
    >functions.


    The number of decimal places should be irrelevant in general, though may
    matter to toFixed and suchlike. The true limit is about 15 *significant
    figures*.


    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
    <URL:http://www.jibbering.com/faq/> JL/RC: 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 John Stockton, Oct 31, 2005
    #17
  18. Re: Help ! Shopping Cart Problem

    JRS: In article <4366154a$0$20411$5a62ac22@per-qv1-newsreader-
    01.iinet.net.au>, dated Mon, 31 Oct 2005 22:59:54, seen in
    news:comp.lang.javascript, RobG <> posted :
    >RobG wrote:
    >[...]
    >> While investigating the above, I noticed that Firefox has some
    >> unexpected (buggy?) behaviour indicated below.

    >
    >Further testing in Safari 1.0.3 showed that is has no native toFixed
    >method and the FAQ's suggested routine fails beyond 8 decimal places:
    >
    > i FAQ toFixed(i)
    > 7 6.6666667
    > 8 6.66666667
    > 9 2.147483647
    > 10 0.2147483647
    > 11 0.02147483647
    > 12 0.002147483647


    That needs investigating. It could be explained by Safari 1.0.3 using
    IEEE Single or similar instead of IEEE Double.

    Your best move, to discover more, might be to take the FAQ method, split
    up the arithmetic statements so that each was as simple as possible, put
    alerts between, and see where it goes wrong - or similar.

    Test what 0.06+0.01 gives ; if it's not 0.06999999999999999 with 17
    decimal places, worry about that instead.

    Aha! 2147483647 + 1 is a well-known power of 2 : 2^31 in fact. Maybe
    1.0.3 implements Math.round(X) as something like, but not matching, X|0.

    You could replace
    String(Math.round(X)) by String(X+0.5).replace(/\..*/, "")
    to see what happens.


    >It would seem that the toFixed suggested in the FAQ does not take
    >enough consideration of the shortcomings or vagaries of floating point
    >arithmetic in various browsers.


    Nothing beyond 14-15 digits is arithmetically meaningful, though ECMA
    may define a specific result.


    FAQ 4.6 is based on an older version of my code, for current see in my
    js-round.htm; I think that page makes it clear enough that the methods
    are intended to give correct meaningful results when used in a
    meaningful manner, and will not necessarily agree to every digit with
    toFixed or other code.

    --
    © John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4 ©
    <URL:http://www.jibbering.com/faq/> JL/RC: 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 John Stockton, Nov 2, 2005
    #18
    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. nicholas

    need some help with shopping cart

    nicholas, Nov 30, 2004, in forum: ASP .Net
    Replies:
    7
    Views:
    445
    nicholas
    Nov 30, 2004
  2. Craig

    ASP Shopping Cart Help Needed

    Craig, Jul 17, 2003, in forum: ASP General
    Replies:
    1
    Views:
    113
    Ray at
    Jul 17, 2003
  3. isaac2004

    help with using shopping cart totals

    isaac2004, Feb 24, 2006, in forum: ASP General
    Replies:
    7
    Views:
    147
    Paxton
    Feb 25, 2006
  4. Randi

    Help with shopping cart problem

    Randi, Apr 3, 2004, in forum: Javascript
    Replies:
    1
    Views:
    91
    Michael Winter
    Apr 3, 2004
  5. Stuincalif
    Replies:
    1
    Views:
    224
    Keith Keller
    Feb 1, 2006
Loading...

Share This Page