# Help ! Shopping Cart Problem

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

1. ### Phil McKrakenGuest

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)

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.)

<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>
<body><center>

<form method="post" name="orderform" action="mailto:"
enctype="text/plain">
<table bgcolor="#EFEFEF" border="0" cellspacing="0"
<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

2. ### RobGGuest

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)
>

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:

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

3. ### Phil McKrakenGuest

>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
4. ### Randy WebbGuest

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,
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
5. ### LeeGuest

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)
>

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
6. ### Phil McKrakenGuest

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
7. ### Dr John StocktonGuest

Help ! Shopping Cart Problem

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.

--
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
8. ### Dr John StocktonGuest

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)
>

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.

--
<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.

Dr John Stockton, Oct 29, 2005
9. ### RobGGuest

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

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.

<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>
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
10. ### Dr John StocktonGuest

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.

--
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
11. ### Dr John StocktonGuest

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 ?

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

Don't forget to read the newsgroup FAQ.

--
<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.

Dr John Stockton, Oct 30, 2005
12. ### Dr John StocktonGuest

Help ! Shopping Cart Problem

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

--
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
13. ### Randy WebbGuest

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
14. ### RobGGuest

Re: Help ! Shopping Cart Problem

Dr John Stockton wrote:
> 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

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

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
15. ### RobGGuest

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
16. ### Dr John StocktonGuest

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.

--
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
17. ### Dr John StocktonGuest

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

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*.

--
<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.

Dr John Stockton, Oct 31, 2005
18. ### Dr John StocktonGuest

Re: Help ! Shopping Cart Problem

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

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.

--