arithmatical headache (Dr J?)

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • J. J. Cale

    arithmatical headache (Dr J?)

    FOA I want to apologize because the page below is in Hebrew and you'll see
    giberish. But for the brave here is the link. www.carmenchange.com Either
    the left or right select box must be set to default (local currency)
    otherwise it evaluates the sale with the foreign currencies. Enter the
    amount under the foreign currency. Every once in a while if fudges. 2.50 X
    10 =24.9........06

    for those who can deal with the code
    these functions read a file (jk.js) whose format is
    var curr1=new Array();
    curr1.name="nam e";
    curr1.buy='4.46 00';
    curr1.sell='4.3 900';
    curr1.rep='4.14 80';
    .....
    currn = etc;
    the html contains two select boxes named "inCurrency " and "outCurrenc y" and
    two text inputs for them and the functions below process the input from the
    text inputs. I've only tested with numbers so feed it at your own risk!!
    There are slight differences in the two functions below but both 'seem' to
    behave the same. I could really use some help here. I just want to multiply
    two values and reformat them. Maybe regexes would be better but I'm weak.
    BTW I'm testing with IE5.0 on (phtu) Windows 98
    function setOutPrice(amo unt) {
    // typeof amount // returns number
    if(isNaN(parseI nt(amount))) return false; // extra check for good integer
    if(!document.fo rms[0].outCurrency.se lectedIndex) return;
    var a,b,obj=documen t.forms[0];
    if(obj.inCurren cy.selectedInde x) return;
    // I have tried replacing the eval with
    // b=window["curr"+obj.outC urrency.selecte dIndex]; b=b.buy;
    // and the results are slightly different but just as bad
    b=eval("curr"+o bj.outCurrency. selectedIndex+" .buy");
    a=parseInt(amou nt)*parseFloat( b);
    obj.inPutPrice. value=fixString (a);
    }
    function setInPrice(amou nt) {
    oObj=document.f orms[0].outCurrency;
    iObj=document.f orms[0].inCurrency;
    if(isNaN(parseI nt(amount))||!i Obj.selectedInd ex) return;
    var a,b;
    if(oObj.selecte dIndex&&iObj.se lectedIndex) {
    forCurrTrans(oO bj,iObj);
    return;
    }
    b=eval('curr'+i Obj.selectedInd ex+'.sell');
    a=amount*b;
    document.forms[0].outPutPrice.va lue=fixString(a );
    }
    function fixString(amt) { // trying to fix the results and format
    var a = parseInt(amt*10 0)/100+'';
    var b=a.indexOf('.' );
    if(b==-1) a+='.00';
    if(a.length-b==2) a+='0';
    return a;
    }



  • Michael Winter

    #2
    Re: arithmatical headache (Dr J?)

    On Tue, 28 Sep 2004 12:09:15 +0200, J. J. Cale <photom@netvisi on.net.il>
    wrote:
    [color=blue]
    > FOA I want to apologize because the page below is in Hebrew and you'll
    > see giberish.[/color]

    If a character set is specified, a visitor will only see gibberish if they
    don't have the required fonts. The ISO character sets are ISO-8859-8 and
    ISO-8859-8-i. The difference between them, as I understand it, is that the
    -i version requires the script to be written in the order, right-to-left.

    Preferably, this information will be sent by the server, but if that can't
    be arranged, add a META element:

    <meta http-equiv="Content-Type"
    content="text/html; charset=iso-8859-8">
    or
    <meta http-equiv="Content-Type"
    content="text/html; charset=iso-8859-8-i">

    I also strongly suggest that the mark-up is fixed. The page doesn't render
    correctly in its current state. See

    <URL:http://validator.w3.or g/check?uri=http% 3A%2F%2Fwww.car menchange.com%2 F&charset=iso-8859-8&doctype=Inlin e&verbose=1>

    for a list of current errors. Note that this is with a forced character
    set. The document couldn't be validated without overriding that particular
    setting. It should be noted that the first error is the lack of a DOCTYPE.
    All new pages should be written to a Strict DTD, which provides a more
    consistent rendering across user agents. See

    <URL:http://www.w3.org/TR/html4/struct/global.html#h-7.2>

    for more information.

    [snip]
    [color=blue]
    > Every once in a while if fudges. 2.50 X 10 =24.9........06[/color]

    Currency calculations are best performed with scaled integers. For a
    start, this allows a simple Math.round() call to round a value, rather
    than something like

    Math.round(valu e * 100) / 100;
    [color=blue]
    > for those who can deal with the code
    > these functions read a file (jk.js) whose format is
    > var curr1=new Array();
    > curr1.name="nam e";
    > curr1.buy='4.46 00';
    > curr1.sell='4.3 900';
    > curr1.rep='4.14 80';
    > ....
    > currn = etc;[/color]

    Those identifiers aren't arrays, they're objects. Surely something like:

    function Currency(n, b, r, s) {
    this.name = n; this.buy = b; this.rep = r; this.sell = s;
    }

    var curr = [
    new Currency('name' , '4.5300', '4.4781', '4.4400'),
    new Currency('name' , '5.5800', '5.5249', '4.4500'),
    // etc...
    new Currency('name' , '6.5555', '6.3174', '6.1500')
    ];

    would be more appropriate. Your lookup is then reduced to:

    curr[elem.selectedIn dex - 1].buy

    assuming you want to ignore the first option. It also means you don't need
    the numCurrs value as curr.length will give you the same result.

    However, I must ask why those numbers are specified as strings. From a
    quick look at the rest of the script, the values are only treated as
    numbers, so what's the point? In my opinion, numbers that will be used for
    arithmetic should be stored in a format that facilitates that. If they
    need to be displayed, write a function that formats them as desired.

    [snip]
    [color=blue]
    > function setOutPrice(amo unt) {
    > // typeof amount // returns number
    > if(isNaN(parseI nt(amount))) return false; // extra check for good
    > integer[/color]

    If amount is a number, why are you using parseInt?
    [color=blue]
    > if(!document.fo rms[0].outCurrency.se lectedIndex) return;[/color]

    As selectedIndex can also be -1, it would be better to check that it was
    below one.
    [color=blue]
    > var a,b,obj=documen t.forms[0];
    > if(obj.inCurren cy.selectedInde x) return;[/color]

    Similarly, this would be better as a check for greater than zero. It's
    also rather inconsistent to use a full reference for outCurrency, but not
    here. Any reason?
    [color=blue]
    > // I have tried replacing the eval with
    > // b=window["curr"+obj.outC urrency.selecte dIndex]; b=b.buy;
    > // and the results are slightly different but just as bad
    > b=eval("curr"+o bj.outCurrency. selectedIndex+" .buy");
    > a=parseInt(amou nt)*parseFloat( b);
    > obj.inPutPrice. value=fixString (a);
    > }
    > function setInPrice(amou nt) {
    > oObj=document.f orms[0].outCurrency;
    > iObj=document.f orms[0].inCurrency;
    > if(isNaN(parseI nt(amount))||!i Obj.selectedInd ex) return;[/color]

    Again, check for less than one and still why parseInt on a number?
    [color=blue]
    > var a,b;[/color]

    You might want to use better identifier names.
    [color=blue]
    > if(oObj.selecte dIndex&&iObj.se lectedIndex) {
    > forCurrTrans(oO bj,iObj);
    > return;
    > }
    > b=eval('curr'+i Obj.selectedInd ex+'.sell');
    > a=amount*b;
    > document.forms[0].outPutPrice.va lue=fixString(a );
    > }
    > function fixString(amt) { // trying to fix the results and format
    > var a = parseInt(amt*10 0)/100+'';[/color]

    You do love parseInt, don't you. By the way, what if the user enters a
    real (decimal) number?
    [color=blue]
    > var b=a.indexOf('.' );
    > if(b==-1) a+='.00';
    > if(a.length-b==2) a+='0';
    > return a;
    > }[/color]

    I think it would be easier to rewrite this code, and the rest on the site,
    rather than attempt to fix it all. Particularly as it contains IE-isms.
    It's also a bad idea to change the value on a key press. Use a button.

    I would present a rewritten version, but as I'm still not sure what is
    supposed to be happening here, I can't.

    Mike

    --
    Michael Winter
    Replace ".invalid" with ".uk" to reply by e-mail.

    Comment

    • John G Harris

      #3
      Re: arithmatical headache (Dr J?)

      In article <41593861$1@new s.012.net.il>, J. J. Cale
      <photom@netvisi on.net.il> writes[color=blue]
      >FOA I want to apologize because the page below is in Hebrew and you'll see
      >giberish. But for the brave here is the link. www.carmenchange.com Either
      >the left or right select box must be set to default (local currency)
      >otherwise it evaluates the sale with the foreign currencies. Enter the
      >amount under the foreign currency. Every once in a while if fudges. 2.50 X
      >10 =24.9........06[/color]

      See FAQ 4.7 and then 4.6.
      [color=blue]
      >for those who can deal with the code
      >these functions read a file (jk.js) whose format is
      >var curr1=new Array();
      >curr1.name="na me";
      >curr1.buy='4.4 600';
      >curr1.sell='4. 3900';
      >curr1.rep='4.1 480';
      >....
      >currn = etc;[/color]
      <snip>

      There are two awkward things about this code you should consider
      avoiding next time.

      First, new Array() would be better as new Object() . You don't need
      the numeric indexes that Array gives you so why ask for them. Also,
      Object doesn't have a length property so its value can't confuse you.

      Second, why not write curr[1] instead of curr1 . It avoids you having
      to write all those eval expressions later on.
      b=curr[obj.outCurrency .selectedIndex].buy;
      is simpler, easier to read, and probably faster than
      b=eval("curr"+o bj.outCurrency. selectedIndex+" .buy");

      Your jk.js file would now be
      var curr = new Array(); // This one is a real array
      curr[1] = new Object();
      curr[1].name = "name";
      ...
      curr[2] = new Object();
      ...

      or you could write
      curr[1] = { name:"name", buy:'4.4600', ... };

      John
      --
      John Harris

      Comment

      • J. J. Cale

        #4
        Re: arithmatical headache (Dr J?)

        thanks to everyone who resoponded
        Michael hi I have tried to implement your changes. I included a DOCTYPE but
        no headers. Actually the program outputs what I need in IE5.0. As per your
        and John's advice the js file is hardwired to the following.
        var hour='08:32';
        var date='28/09/2004';
        var aCurr = new Array();
        function Currency(sCurrn ame,sFlagname,f Rep,fSell,fBuy) {
        this.name=sCurr name;
        this.flag=sFlag name;
        this.rep=fRep;
        this.sell=fSell ;
        this.buy=fBuy;
        }
        aCurr[0] = new Currency('???? ???"?','usa',4. 5486,4.4900,4.6 000);
        aCurr[1] = new Currency('????' ,'eur',5.4935,5 .4200,5.5500);
        aCurr[2] = new Currency('???? ???????','eng', 8.3062,8.1300,8 .4500);
        aCurr[3] = new Currency('???? ???????','swi', 3.5718,3.4900,3 .6300);
        aCurr[4] = new Currency('???? ????','can',3.4 508,3.3750,3.51 00);
        aCurr[5] = new Currency('?? ????','jap',4.0 748,3.9900,4.15 00);
        aCurr[6] = new Currency('???? ???????','aus', 3.2027,3.1350,3 .2600);
        aCurr[7] = new Currency('???? ?????','jor',6. 4038,6.2100,6.5 800);
        I understand after reading the FAQ that there is no reliable way to
        add/mult/div floating point values.The code now works 'in my Browser'. BTW
        the problem was one too many parseInt calls. particularly this.
        var a = parseInt(amt*10 0)/100; should be Math.round(amt* 100)/100;
        You disapproved of this. I got it from searching Dr John Stockton some time
        ago. He used it in rounding or 'financial' formatting. I didn't remember it
        correctly.
        <snip>[color=blue]
        > Currency calculations are best performed with scaled integers. For a
        > start, this allows a simple Math.round() call to round a value, rather
        > than something like Math.round(valu e * 100) / 100;[/color]
        Not sure what you mean. I need a dollars and cents format (15.20). How can
        multiplying two integers give me a floating point result. e.g. amount (10) *
        rate (4.59)
        <snip>[color=blue]
        > However, I must ask why those numbers are specified as strings. From a
        > quick look at the rest of the script, the values are only treated as
        > numbers, so what's the point?[/color]
        programatic output. The good news is I can program in c/c++ so I can change
        the output to the js file[color=blue]
        >In my opinion, numbers that will be used for
        > arithmetic should be stored in a format that facilitates that. If they
        > need to be displayed, write a function that formats them as desired.[/color]
        could you show an example
        [snip][color=blue]
        > It's also rather inconsistent to use a full reference for outCurrency, but[/color]
        not[color=blue]
        > here. Any reason?[/color]
        outCurrency and inCurrency are the names of the select lists not ids. Do I
        have another option?[color=blue]
        > You do love parseInt, don't you.[/color]
        fools attempts to make the browser do his bidding.[color=blue]
        > By the way, what if the user enters a real (decimal) number?[/color]
        only testing with whole numbers. I can include a test to trap unwanted
        input.[color=blue]
        >As selectedIndex can also be -1, it would be better to check that it was
        >below one.[/color]
        under what conditions can a select object selectedIndex equal-1 except maybe
        if it has no options(not tested)?[color=blue]
        > I think it would be easier to rewrite this code, and the rest on the site,
        > rather than attempt to fix it all. Particularly as it contains IE-isms.[/color]
        point me to them and I will happily change them theWorld-MS=aBetterPlace
        IMHO[color=blue]
        > It's also a bad idea to change the value on a key press. Use a button.[/color]
        could you elaborate? I'm just trying to automate for the user.[color=blue]
        > I would present a rewritten version, but as I'm still not sure what is
        > supposed to be happening here, I can't.[/color]
        Thanks anyway. This is a foreign currency calculator of sorts. Both select
        lists are identical. The default (first option) in both lists is the local
        currency so choosing a foreign currency from inCurrency means you should
        choose the default in the outCurrency list and vice-versa. (yes there is an
        option for the transaction to be made if both lists select different foreign
        currencies.. and it computes the change in the local currency :>)
        I don't want you to write my code for me but I would be interested to know
        what else you would do differently
        here is fresh code and hopefully better optimised
        Thank you for your time and valuable help.
        Jimbo
        function setOutPrice(amo unt) {
        if(document.for ms[0].outCurrency.se lectedIndex<1) return;
        var obj=document.fo rms[0];
        if(obj.inCurren cy.selectedInde x>0) return;

        obj.inPutPrice. value=fixString (amount*aCurr[obj.outCurrency .selectedIndex-1]
        ..buy);
        }
        function setInPrice(amou nt) {
        oObj=document.f orms[0].outCurrency;
        iObj=document.f orms[0].inCurrency;
        if(iObj.selecte dIndex<1) return;
        if(oObj.selecte dIndex>0&&iObj. selectedIndex>0 ) {
        forCurrTrans(oO bj,iObj);
        return;
        }

        document.forms[0].outPutPrice.va lue=fixString(a mount*aCurr[iObj.selectedIn de
        x-1].sell);
        }
        function fixString(amt) {
        var a = (Math.round(amt *100)/100)+'';
        var b=a.indexOf('.' );
        if(b==-1) a+='.00';
        if(a.length-b==2) a+='0';
        return a;
        }



        Comment

        • Andrew Thompson

          #5
          Re: arithmatical headache (Dr J?)

          On Wed, 29 Sep 2004 16:13:02 +0200, J. J. Cale wrote:
          [color=blue]
          > Actually the program outputs what I need in IE5.0.[/color]

          IE is the worst browser to test in, because it will allow
          you to 'get way' with too many things that other browsers
          will not. It also encourages you to use (and come to rely
          on) things that are for 'IE only'.

          If your page is for the internet, and you are using Win, the
          minimum you should test in is IE/Moz(Netscape/Firefox)/Opera.
          A 'text only' browser as well, if you are really serious
          about accessibility.

          --
          Andrew Thompson
          http://www.PhySci.org/codes/ Web & IT Help
          http://www.PhySci.org/ Open-source software suite
          http://www.1point1C.org/ Science & Technology
          http://www.lensescapes.com/ Images that escape the mundane

          Comment

          • Dr John Stockton

            #6
            Re: arithmatical headache (Dr J?)

            JRS: In article <415ac303$1@new s.012.net.il>, dated Wed, 29 Sep 2004
            16:13:02, seen in news:comp.lang. javascript, J. J. Cale
            <photom@netvisi on.net.il> posted :
            [color=blue]
            >var date='28/09/2004';[/color]

            Don't use that form D/M/Y ; it will fail for some users if D!=M && D<13
            Use instead '2004/09/28' Y/M/D which AFAIK is always correctly
            interpreted. Should be easy for you as Israelis write backwards anyway.

            General note - use blank lines in your writing, as is customary. I find
            it unreadable without.

            --
            © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00 MIME. ©
            Web <URL:http://www.merlyn.demo n.co.uk/> - w. FAQish topics, links, acronyms
            PAS EXE etc : <URL:http://www.merlyn.demo n.co.uk/programs/> - see 00index.htm
            Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm etc.

            Comment

            • J. J. Cale

              #7
              Re: arithmatical headache (Dr J?)


              "Dr John Stockton" <spam@merlyn.de mon.co.uk> wrote in message
              news:fK$buBDMfz WBFwcv@merlyn.d emon.co.uk...[color=blue]
              > JRS: In article <415ac303$1@new s.012.net.il>, dated Wed, 29 Sep 2004
              > 16:13:02, seen in news:comp.lang. javascript, J. J. Cale
              > <photom@netvisi on.net.il> posted :
              >[color=green]
              > >var date='28/09/2004';[/color]
              >
              > Don't use that form D/M/Y ; it will fail for some users if D!=M && D<13
              > Use instead '2004/09/28' Y/M/D which AFAIK is always correctly
              > interpreted. Should be easy for you as Israelis write backwards anyway.[/color]

              Hi Dr J. (may I?)
              I was hoping to catch your attention in the OP to get some help from you on
              the format or the computations. Maybe a regex that would return some more
              stable results. BTW we don't write backwords just from right to left (<;
              our 'formal' date format is D/M/Y.
              [color=blue]
              > General note - use blank lines in your writing, as is customary. I find
              > it unreadable without.[/color]

              thank you. Is this better. I do try.
              [color=blue]
              > --
              > © John Stockton, Surrey, UK. ?@merlyn.demon. co.uk Turnpike v4.00[/color]
              MIME. ©[color=blue]
              > Web <URL:http://www.merlyn.demo n.co.uk/> - w. FAQish topics, links,[/color]
              acronyms[color=blue]
              > PAS EXE etc : <URL:http://www.merlyn.demo n.co.uk/programs/> - see[/color]
              00index.htm[color=blue]
              > Dates - miscdate.htm moredate.htm js-dates.htm pas-time.htm critdate.htm[/color]
              etc.


              Comment

              • George Hester

                #8
                Re: arithmatical headache (Dr J?)

                Yeah if he just set the the Content-Type character set correctly most of us would see it in the appropriate language.

                --
                George Hester
                _______________ _______________ ____
                "Michael Winter" <M.Winter@bluey onder.co.invali d> wrote in message news:opse1tg9y0 x13kvk@atlantis ...[color=blue]
                > On Tue, 28 Sep 2004 12:09:15 +0200, J. J. Cale <photom@netvisi on.net.il>
                > wrote:
                > [color=green]
                > > FOA I want to apologize because the page below is in Hebrew and you'll
                > > see giberish.[/color]
                >
                > If a character set is specified, a visitor will only see gibberish if they
                > don't have the required fonts. The ISO character sets are ISO-8859-8 and
                > ISO-8859-8-i. The difference between them, as I understand it, is that the
                > -i version requires the script to be written in the order, right-to-left.
                >
                > Preferably, this information will be sent by the server, but if that can't
                > be arranged, add a META element:
                >
                > <meta http-equiv="Content-Type"
                > content="text/html; charset=iso-8859-8">
                > or
                > <meta http-equiv="Content-Type"
                > content="text/html; charset=iso-8859-8-i">
                >
                > I also strongly suggest that the mark-up is fixed. The page doesn't render
                > correctly in its current state. See
                >
                > <URL:http://validator.w3.or g/check?uri=http% 3A%2F%2Fwww.car menchange.com%2 F&charset=iso-8859-8&doctype=Inlin e&verbose=1>
                >
                > for a list of current errors. Note that this is with a forced character
                > set. The document couldn't be validated without overriding that particular
                > setting. It should be noted that the first error is the lack of a DOCTYPE.
                > All new pages should be written to a Strict DTD, which provides a more
                > consistent rendering across user agents. See
                >
                > <URL:http://www.w3.org/TR/html4/struct/global.html#h-7.2>
                >
                > for more information.
                >
                > [snip]
                > [color=green]
                > > Every once in a while if fudges. 2.50 X 10 =24.9........06[/color]
                >
                > Currency calculations are best performed with scaled integers. For a
                > start, this allows a simple Math.round() call to round a value, rather
                > than something like
                >
                > Math.round(valu e * 100) / 100;
                > [color=green]
                > > for those who can deal with the code
                > > these functions read a file (jk.js) whose format is
                > > var curr1=new Array();
                > > curr1.name="nam e";
                > > curr1.buy='4.46 00';
                > > curr1.sell='4.3 900';
                > > curr1.rep='4.14 80';
                > > ....
                > > currn = etc;[/color]
                >
                > Those identifiers aren't arrays, they're objects. Surely something like:
                >
                > function Currency(n, b, r, s) {
                > this.name = n; this.buy = b; this.rep = r; this.sell = s;
                > }
                >
                > var curr = [
                > new Currency('name' , '4.5300', '4.4781', '4.4400'),
                > new Currency('name' , '5.5800', '5.5249', '4.4500'),
                > // etc...
                > new Currency('name' , '6.5555', '6.3174', '6.1500')
                > ];
                >
                > would be more appropriate. Your lookup is then reduced to:
                >
                > curr[elem.selectedIn dex - 1].buy
                >
                > assuming you want to ignore the first option. It also means you don't need
                > the numCurrs value as curr.length will give you the same result.
                >
                > However, I must ask why those numbers are specified as strings. From a
                > quick look at the rest of the script, the values are only treated as
                > numbers, so what's the point? In my opinion, numbers that will be used for
                > arithmetic should be stored in a format that facilitates that. If they
                > need to be displayed, write a function that formats them as desired.
                >
                > [snip]
                > [color=green]
                > > function setOutPrice(amo unt) {
                > > // typeof amount // returns number
                > > if(isNaN(parseI nt(amount))) return false; // extra check for good
                > > integer[/color]
                >
                > If amount is a number, why are you using parseInt?
                > [color=green]
                > > if(!document.fo rms[0].outCurrency.se lectedIndex) return;[/color]
                >
                > As selectedIndex can also be -1, it would be better to check that it was
                > below one.
                > [color=green]
                > > var a,b,obj=documen t.forms[0];
                > > if(obj.inCurren cy.selectedInde x) return;[/color]
                >
                > Similarly, this would be better as a check for greater than zero. It's
                > also rather inconsistent to use a full reference for outCurrency, but not
                > here. Any reason?
                > [color=green]
                > > // I have tried replacing the eval with
                > > // b=window["curr"+obj.outC urrency.selecte dIndex]; b=b.buy;
                > > // and the results are slightly different but just as bad
                > > b=eval("curr"+o bj.outCurrency. selectedIndex+" .buy");
                > > a=parseInt(amou nt)*parseFloat( b);
                > > obj.inPutPrice. value=fixString (a);
                > > }
                > > function setInPrice(amou nt) {
                > > oObj=document.f orms[0].outCurrency;
                > > iObj=document.f orms[0].inCurrency;
                > > if(isNaN(parseI nt(amount))||!i Obj.selectedInd ex) return;[/color]
                >
                > Again, check for less than one and still why parseInt on a number?
                > [color=green]
                > > var a,b;[/color]
                >
                > You might want to use better identifier names.
                > [color=green]
                > > if(oObj.selecte dIndex&&iObj.se lectedIndex) {
                > > forCurrTrans(oO bj,iObj);
                > > return;
                > > }
                > > b=eval('curr'+i Obj.selectedInd ex+'.sell');
                > > a=amount*b;
                > > document.forms[0].outPutPrice.va lue=fixString(a );
                > > }
                > > function fixString(amt) { // trying to fix the results and format
                > > var a = parseInt(amt*10 0)/100+'';[/color]
                >
                > You do love parseInt, don't you. By the way, what if the user enters a
                > real (decimal) number?
                > [color=green]
                > > var b=a.indexOf('.' );
                > > if(b==-1) a+='.00';
                > > if(a.length-b==2) a+='0';
                > > return a;
                > > }[/color]
                >
                > I think it would be easier to rewrite this code, and the rest on the site,
                > rather than attempt to fix it all. Particularly as it contains IE-isms.
                > It's also a bad idea to change the value on a key press. Use a button.
                >
                > I would present a rewritten version, but as I'm still not sure what is
                > supposed to be happening here, I can't.
                >
                > Mike
                >
                > --
                > Michael Winter
                > Replace ".invalid" with ".uk" to reply by e-mail.[/color]

                Comment

                • Michael Winter

                  #9
                  Re: arithmatical headache (Dr J?)

                  On Wed, 29 Sep 2004 16:13:02 +0200, J. J. Cale <photom@netvisi on.net.il>
                  wrote:

                  [snip]
                  [color=blue][color=green]
                  >> Currency calculations are best performed with scaled integers. For a
                  >> start, this allows a simple Math.round() call to round a value, rather
                  >> than something like Math.round(valu e * 100) / 100;[/color]
                  >
                  > Not sure what you mean. I need a dollars and cents format (15.20). How
                  > can multiplying two integers give me a floating point result. e.g.
                  > amount (10) * rate (4.59)[/color]

                  With

                  10 x 4.59

                  depending on the possibility to represent the resulting 0.9 in IEEE-754,
                  you may or may not end up with an accurate solution. However, if you scale
                  the cost by one hundred

                  10 x 459

                  will always yield 4590. It's then just a matter of separating the last two
                  digits to get the decimal and integer portions.

                  Of course, things must change a bit when you're working with two sets of
                  real numbers as multiplication will alter the result by the product of the
                  scale applied to each number. So, scaling one operand by 10, the other by
                  100, and multiplying will yield an answer 1000 times larger.

                  In your case, the user will enter a real number with a maximum of two
                  decimal places, and you'll multiply it by the exchange rate which is to
                  four decimal places.

                  Scaling the user input is simple: ensure the string represents a real
                  (appending ".00" if necessary), remove the decimal place concatenating the
                  numbers either side, and convert the resulting string to a number. The
                  scaling of the exchange rate value is just as simple: output the results
                  from your program already scaled by 10000.

                  An example: 9.56 Shekels as Pounds Sterling.

                  9.56 x 0.1241 = £1.186396

                  956 x 1241 = 1186396 (scaled by 10^6 [100 x 10000])

                  To convert the number to pounds: divide by 10000 (back to pence) and round
                  the number, convert to a string and insert the decimal place two places
                  from the right.

                  As you're only working with real numbers at one place - the end - and any
                  error will be far beyond the precision you require, you'll get accurate
                  results (unless I'm missing something).

                  [snip]
                  [color=blue][color=green]
                  >> In my opinion, numbers that will be used for arithmetic should be
                  >> stored in a format that facilitates that. If they need to be displayed,
                  >> write a function that formats them as desired.[/color]
                  >
                  > could you show an example[/color]
                  [color=blue][color=green]
                  >> It's also rather inconsistent to use a full reference for outCurrency,
                  >> but not here. Any reason?[/color]
                  >
                  > outCurrency and inCurrency are the names of the select lists not ids. Do
                  > I have another option?[/color]

                  I was actually referring to the fact that outCurrency was referenced with:

                  document.forms[0].outCurrency

                  at the start of the setOutPrice function, but with inCurrency and later
                  references to outCurrency used

                  var obj = document.forms[0];

                  obj.inCurrency and obj.outCurrency

                  The best approach is to actually save references to the controls
                  themselves, as you do in the setInPrice function.

                  [snip]
                  [color=blue][color=green]
                  >> By the way, what if the user enters a real (decimal) number?[/color]
                  >
                  > only testing with whole numbers. I can include a test to trap unwanted
                  > input.[/color]

                  But with currency conversion, aren't your users going to convert real
                  numbers?
                  [color=blue][color=green]
                  >> As selectedIndex can also be -1, it would be better to check that it
                  >> was below one.[/color][/color]

                  I'm being overly cautious, here. But I'll answer your question, anyway.
                  [color=blue]
                  > under what conditions can a select object selectedIndex equal -1 except
                  > maybe if it has no options(not tested)?[/color]

                  If no options are selected. Granted, it would be unlikely that it would
                  occur, but strange things can happen. As you don't indicate that a value
                  should be selected, using the selected attribute, behaviour is undefined.
                  That said the majority of browsers will select the first option.

                  So I suppose there are four options:

                  1) Not worry.
                  2) Change the test to exclude zero and -1.
                  3) Set an option to be selected by default.
                  4) Options 2 and 3.
                  [color=blue][color=green]
                  >> I think it would be easier to rewrite this code, and the rest on the
                  >> site, rather than attempt to fix it all. Particularly as it contains
                  >> IE-isms.[/color]
                  >
                  > point me to them and I will happily change them
                  > theWorld-MS=aBetterPlace IMHO[/color]

                  A very progressive attitude. :)

                  1) In the md function

                  a) Referencing the DIV, main, using its id as a global identifier.
                  b) Use of the non-standard children collection.
                  c) Use of the event object as a global.
                  d) Use of the non-standard srcElement property.
                  e) Use of the non-standard parentElement property.

                  2) In the mm function

                  a) 1a, 1b, and 1c.
                  b) Use of the non-standard innerText property.

                  3) In the toggleObjs function

                  a) Referencing the SPAN, aa, using its id as a global identifier.
                  b) Use of the non-standard filters collection.

                  4) In the final SCRIPT element

                  a) Referencing seven elements by their id.

                  If you used feature detection (something else totally that's lacking),
                  some of the above wouldn't be a problem, they just wouldn't work on
                  browsers that didn't support them. You also make extensive use of eval,
                  when there's no need.

                  The use of pixel-perfect absolute positioning is a bad idea. Use a fluid
                  design. There's also an inordinate number of inline styles: use classes
                  wherever possible.
                  [color=blue][color=green]
                  >> It's also a bad idea to change the value on a key press. Use a button.[/color]
                  >
                  > could you elaborate? I'm just trying to automate for the user.[/color]

                  It's a noble enough idea, but the user doesn't need an update after every
                  key stroke. Moreover, it's harder to validate an entry properly if you
                  start testing incomplete entries. A less likely, but still important
                  point, is that the user might not enter a value with the keyboard. It
                  could be pasted with the mouse, with no resulting action.
                  [color=blue][color=green]
                  >> I would present a rewritten version, but as I'm still not sure what is
                  >> supposed to be happening here, I can't.[/color]
                  >
                  > Thanks anyway. This is a foreign currency calculator of sorts.[/color]

                  In that case, try making life somewhat easier for yourself and investigate
                  <URL:http://www.xe.com/> (the Webmasters menu at the top of the page). For
                  the cost of a banner, you can partially customise their interface. That
                  would allow your users to convert between every known currency on the
                  planet. Two things to consider, though:

                  1) Their results won't be in Hebrew. I don't think that would be of much
                  importance, though.
                  2) They use mid-market rates, not the buy and sell rates. You have to pay
                  to get them.

                  [snip]
                  [color=blue]
                  > I don't want you to write my code for me but I would be interested to
                  > know what else you would do differently[/color]

                  I have made a quick version (in English :) for comparison at:

                  <URL:http://www.mlwinter.pw p.blueyonder.co .uk/clj/cale/convert.html>

                  It includes validation and uses the scaled integer technique I was talking
                  about. The exchange values (mid-market rates, not buy/sell) are scaled by
                  100000. As a result of the treatment of the user input, that is scaled by
                  100. At the end of the calculation, the answer remains scaled by 100. This
                  is then rounded by the tc (to currency) function.

                  The main work is performed in the last inner function that begins

                  return (function(f) {

                  The rest is just a series of supporting functions. The domCore object is
                  part of a set of my functions. Here it provides getElementById emulation
                  for older versions of IE. The tz function adds trailing zeros to a string.
                  It's used here to ensure the user's input ends with two digits. The tc
                  function takes a number that represents pennies (cents) and converts it to
                  a string representing pounds/pennies.

                  [snip]
                  [color=blue]
                  > function setOutPrice(amo unt) {
                  > if(document.for ms[0].outCurrency.se lectedIndex<1) return;
                  > var obj=document.fo rms[0];[/color]

                  Place this line first, then use 'obj' with the outCurrency reference in
                  the first line. In addition, you could save the value of
                  outCurrency.sel ectedIndex as it won't change during execution of the
                  function.

                  [snip]
                  [color=blue]
                  > function setInPrice(amou nt) {
                  > oObj=document.f orms[0].outCurrency;
                  > iObj=document.f orms[0].inCurrency;
                  > if(iObj.selecte dIndex<1) return;
                  > if(oObj.selecte dIndex>0&&iObj. selectedIndex>0 ) {[/color]

                  Again, save and use the reference obtained from document.forms[0], and
                  consider saving the value of iObj.selectedIn dex for use here and later in
                  the function.

                  [snip]

                  Mike

                  --
                  Michael Winter
                  Replace ".invalid" with ".uk" to reply by e-mail.

                  Comment

                  • Thomas 'PointedEars' Lahn

                    #10
                    Re: arithmatical headache (Dr J?)

                    John G Harris wrote:
                    [color=blue]
                    > Your jk.js file would now be
                    > var curr = new Array(); // This one is a real array
                    > curr[1] = new Object();
                    > curr[1].name = "name";
                    > ...
                    > curr[2] = new Object();
                    > ...
                    >
                    > or you could write
                    > curr[1] = { name:"name", buy:'4.4600', ... };[/color]

                    Or he could write

                    var curr = [
                    { name:"name", buy:'4.4600', ... },
                    ...
                    ];


                    PointedEars

                    Comment

                    • John G Harris

                      #11
                      Re: arithmatical headache (Dr J?)

                      In article <2073754.Cg0ZlA We9y@PointedEar s.de>, Thomas 'PointedEars'
                      Lahn <PointedEars@we b.de> writes[color=blue]
                      >John G Harris wrote:
                      >[color=green]
                      >> Your jk.js file would now be
                      >> var curr = new Array(); // This one is a real array
                      >> curr[1] = new Object();
                      >> curr[1].name = "name";
                      >> ...
                      >> curr[2] = new Object();
                      >> ...
                      >>
                      >> or you could write
                      >> curr[1] = { name:"name", buy:'4.4600', ... };[/color]
                      >
                      >Or he could write
                      >
                      > var curr = [
                      > { name:"name", buy:'4.4600', ... },
                      > ...
                      > ];[/color]

                      But not if he really did want to index from 1.

                      John
                      --
                      John Harris

                      Comment

                      • Thomas 'PointedEars' Lahn

                        #12
                        Re: arithmatical headache (Dr J?)

                        John G Harris wrote:
                        [color=blue]
                        > In article <2073754.Cg0ZlA We9y@PointedEar s.de>, Thomas 'PointedEars'
                        > Lahn <PointedEars@we b.de> writes[color=green]
                        >>John G Harris wrote:[color=darkred]
                        >>> Your jk.js file would now be
                        >>> var curr = new Array(); // This one is a real array
                        >>> curr[1] = new Object();
                        >>> curr[1].name = "name";
                        >>> ...
                        >>> curr[2] = new Object();
                        >>> ...
                        >>>
                        >>> or you could write
                        >>> curr[1] = { name:"name", buy:'4.4600', ... };[/color]
                        >>
                        >> Or he could write
                        >>
                        >> var curr = [
                        >> { name:"name", buy:'4.4600', ... },
                        >> ...
                        >> ];[/color]
                        >
                        > But not if he really did want to index from 1.[/color]

                        Well, there is a solution:

                        var curr = [
                        null, // or whatever non-reference value you want
                        { name:"name", buy:'4.4600', ... },
                        ...
                        ];


                        PointedEars
                        --
                        Whose cruel idea was it for the word "lisp" to have an "s" in it?

                        Comment

                        Working...