Re: remainder() is not right
- Posted by jacques deschĂȘnes <desja at globetr?tte?.net> May 04, 2008
- 1086 views
In fact remainder(x,y) means q*y+r=x so remainder(-27,3600)= (-27) is ok as 0*3600+(-27)=(-27) remainder(-3627,3600)=(-27) is ok as -1*3600+(-27)=(-3627) remainder(-3627,-3600) = -27 is ok as 1*(-3600)+(-27)=(-3627) remainder(27,-3600) = 27 is ok as 0*3600+ 27 = 27 Jacques DeschĂȘnes CChris wrote: > > > The remainder of x by y, which remainder() is supposed to return, is the > number > with the smallest magnitude and the sign of y such that, if we call it z, x-z > is a multiple of y. > > But remainder() has a quirkier response. For instance: > ?remainder(-27,3600) -- -27, instead of 3573 > ?remainder(-3627,3600) -- ditto > ?remainder(-3627,-3600) -- -27 is correct here > ?remainder(27,-3600) -- 27, instead of -3573 > > Changing remainder()'s behaviour will break any code that works around this > behaviour. So perhaps should we add another function with the appropriate > return > values; perhaps signed_remainder()? > > Notionally, it might work like this: > }}} <eucode> > global function signed_remainder(object a,object b) > integer atom_a,atom_b > atom c > > if find(b,{{},0.0} then > return {} -- not a valid 2nd argument > -- crash("Invalid 2nd argument to remainder()") > end if > atom_a=atom(a) > atom_b=atom(b) > if atom_a!=atom_b then > if atom_a then -- atom,sequence > for i=1 to length(b) do > b[i]=signed_remainder(a,b[i]) > end for > return b > else -- sequence,atom > for i=1 to length(a) do > a[i]=signed_remainder(a[i],b) > end for > return a > end if > elsif atom_a=0 then -- two sequences > if length(a)!=length(b) then > return {} -- let caller handle the mismatch > -- crash("Sequence lengths don't match") > else > for i=1 to length(a) do > a[i]=signed_remainder(a[i],b[i]) > end for > return a > end if > else -- two atoms > c=remainder(a,b) -- smallest magnitude and sign of a > if a<0!=b<0 then > return c+b > else > return c > end if > end function > </eucode> {{{ > > It will be probably better implemented as a builtin if there is a > corresponding > C stdlib function with the desired behaviour. If only to take advantage of the > sequence extension mechanism binary_op() in be_runtime.c provides. > > CChris