1. Round
- Posted by Michael Nelson <mike-nelson-ODAAT at WORLDNET.ATT.NET> Jun 07, 2000
- 619 views
The following code may be of interest: global function unary_function(integer id,object Param) if atom(Param) then return call_func(id,{Param}) end if for i=1 to length(Param) do Param[i]=call_func(id,{Param[i]}) end for return Param end function global function binary_function(integer id,object Param1,object Param2) integer len1,len2 if atom(Param1) then len1=-1 else len1=length(Param1) end if if atom(Param2) then len2=-1 else len2=length(Param2) end if if len1=-1 and len2=-1 then return call_func(id,{Param1,Param2}) end if if len1=-1 then Param1=repeat(Param1,len2) len1=len2 elsif len2=-1 then Param2=repeat(Param2,len1) len2=len1 end if if len1!=len2 then puts(2,"\nSequence length mismatch.\n") ? 1/0 end if for i=1 to len1 do Param1[i]=call_func(id,{Param1[i],Param2[i]}) end for return Param1 end function constant TOLERANCE=1e-10 function round_atom(atom a,integer places) integer int atom adjust adjust=power(10,places) a=a*adjust+.5 int=floor(a) if a-int<TOLERANCE and remainder(int,2)!=0 then int-=1 end if return int/adjust end function constant ROUND_ATOM=routine_id("round_atom") global function round(object x,object places) return binary_function(ROUND_ATOM,x,places) end function First look at round_atom(). This rounds an atom to the specified number of places (use 0 to round to an integer). The floor(a+.5) idea works except for exact .5 remainders--it can round these wrong. The code I have given above aproximates the IEEE standard "Banker's Rounding": round .4999999 down, round .5000001 up, round exactly .5 to the nearest even number. This can't be done exactly with Euphoria's binary floating point atoms, but the tolerance factor gets it right most of the time. (Getting it right every time requires binary coded decimal fp.) If you prefer a 5/4 roundoff, where exactly .5 is rounded up change if a-int<TOLERANCE and remainder(int,2)!=0 then int-=1 end if to if a-int<TOLERANCE and a<=0 then int-=1 end if The function round() extends this to allow for sequences so that ? round(1.5,0) -->prints 2 ? round(3.14159,{0,1,2,3,4}) -->prints {3,3.1,3.14,3.142,3.1416} ? round({15.786,12.3455},2) -->prints {15.79,12.35} and so forth. The utility functions unary_function() and binary_function() are used apply functions written to use atoms to sequences. Use unary_function() if the atomic function takes 1 argument, binary_function() if 2. -- Mike Nelson
2. Re: Round
- Posted by Aidan Bindoff <abindoff at ONE.NET.AU> Jun 09, 2000
- 618 views
To answer (c)koda's original question, what you are looking for is something like the old G(ee)W(hizz) Basic integer command. This converts a decimal to an integer - quite handy for some things. The way I do it is: function force_integer(atom number) number=floor(sqrt(number*number)+0.5)* (number/(sqrt(number*number)) return number end function I also have this in a loop to round strings, as a round function which has number_of_decimal_places as an argument. The absolute value (sqrt(num*num)) is multiplied by power(10,num_places) and the final result divided by power(10,num_places). Kind Regards, Aidan
3. Re: Round
- Posted by "Lucius L. Hilley III" <lhilley at CDC.NET> Jun 09, 2000
- 633 views
I have some things to address here that I am surprised haven't been mentioned by someone else yet. Your code.... sqrt(number*number)--abs() I only see one flaw in this absolute value code. Yes, it works. Yes, it will most likely work in every case that you ever use it in. No it doesn't work for all atoms. In fact it doesn't come close to working with all atoms. Example: I start with a with a value that is much less than half the atoms possible. a = largest_possible_atom / 3 a = sqrt(a*a)--Oops.... the poor thang crashed. --lets say way break the above line down and see why. a = (a*a)--Oops... the poor than crashed... --Now let's analyze why. TRUE or FALSE !!! largest_possible_atom is greater than 3? (6/2) * (6/2) equals 9? 9 is greater than 6? Assume that 6 is the largest_possible_atom You know that 9 is greater than 6. Therefore 9 is large enough to crash the program. You know that Half of 6 is 3 AND 3 times 3 = 9 You can see that your math will keep more than half of the possible atoms from being evaluated. function your_abs(atom a)--You return sqrt(a * a) end function function my_abs() if a > 0 then return a else return -a end if end function NEXT You said "I also have this in a loop to round strings". I assume you mean the following example. i = force_integer(4.3) -- i = 4 s = repeat(i, 3)--{4.3, 4.3, 4.3} for A = 1 to length(s) do s[A] = force_integer(s[A]) end for --s = {4, 4, 4} If this is the case and the method in which you handle a long set of integers, then wake up and realize the power of sequences. The math will work on an entire sequence just as easily as it will work on and individual atom. In your code listed below just change: function force_integer(atom number) TO function force_integer(object number) Lucius L. Hilley III lhilley at cdc.net +----------+--------------+--------------+ | Hollow | ICQ: 9638898 | AIM: LLHIII | | Horse +--------------+--------------+ | Software | http://www.cdc.net/~lhilley | +----------+-----------------------------+ ----- Original Message ----- From: "Aidan Bindoff" <abindoff at one.net.au> To: <EUPHORIA at LISTSERV.MUOHIO.EDU> Sent: Thursday, June 08, 2000 7:02 PM Subject: Re: Round > To answer (c)koda's original question, what you are looking for is > something like the old G(ee)W(hizz) Basic integer command. > This converts a decimal to an integer - quite handy for some things. > The way I do it is: > > function force_integer(atom number) > number=floor(sqrt(number*number)+0.5)* > > (number/(sqrt(number*number)) > return number > end function > > I also have this in a loop to round strings, as a round function which has > number_of_decimal_places as an argument. The absolute value (sqrt(num*num)) > is multiplied by power(10,num_places) and the final result divided by > power(10,num_places). > > Kind Regards, > Aidan >
4. Re: Round
- Posted by Aidan Bindoff <abindoff at ONE.NET.AU> Jun 10, 2000
- 607 views
Lucius, thankyou for pointing that out. In my applications I hadn't even considered atoms that big. Also, making a loop does seem pretty convoluted when you can just use force_int(object) - but that's Euphoria! You don't always wake up and smell the coffee with everything different thing you do... Kind Regards, Aidan ----- Original Message ----- From: Lucius L. Hilley III <lhilley at CDC.NET> To: <EUPHORIA at LISTSERV.MUOHIO.EDU> Sent: Friday, June 09, 2000 10:55 PM Subject: Re: Round > I have some things to address here that I am surprised haven't been > mentioned by someone else yet. > > Your code.... > sqrt(number*number)--abs() > I only see one flaw in this absolute value code. Yes, it works. Yes, it > will most likely work in every case that you ever use it in. No it doesn't > work for all atoms. In fact it doesn't come close to working with all > atoms. > > Example: > I start with a with a value that is much less than half the atoms possible. > > a = largest_possible_atom / 3 > a = sqrt(a*a)--Oops.... the poor thang crashed. > > --lets say way break the above line down and see why. > a = (a*a)--Oops... the poor than crashed... > > --Now let's analyze why. > TRUE or FALSE !!! > largest_possible_atom is greater than 3? > (6/2) * (6/2) equals 9? > 9 is greater than 6? > Assume that 6 is the largest_possible_atom > You know that 9 is greater than 6. > Therefore 9 is large enough to crash the program. > > You know that Half of 6 is 3 AND > 3 times 3 = 9 > You can see that your math will keep more than half of the possible atoms > from being evaluated. > > function your_abs(atom a)--You > return sqrt(a * a) > end function > > function my_abs() > if a > 0 then > return a > else > return -a > end if > end function > > > > NEXT > > You said "I also have this in a loop to round strings". I assume you mean > the following example. > > i = force_integer(4.3) -- i = 4 > s = repeat(i, 3)--{4.3, 4.3, 4.3} > for A = 1 to length(s) do > s[A] = force_integer(s[A]) > end for > --s = {4, 4, 4} > > If this is the case and the method in which you handle a long set of > integers, then wake up and realize the power of sequences. The math will > work on an entire sequence just as easily as it will work on and individual > atom. > > In your code listed below just change: > > function force_integer(atom number) > TO > function force_integer(object number) > > Lucius L. Hilley III > lhilley at cdc.net > +----------+--------------+--------------+ > | Hollow | ICQ: 9638898 | AIM: LLHIII | > | Horse +--------------+--------------+ > | Software | http://www.cdc.net/~lhilley | > +----------+-----------------------------+