develooper Front page | perl.perl6.language | Postings from May 2005

Re: mod/div

Thread Previous | Thread Next
From:
Mark Reed
Date:
May 31, 2005 13:52
Subject:
Re: mod/div
Message ID:
BEC246CB.66A1%mark.reed@turner.com
On 2005-05-30 05:15, "TSa (Thomas SandlaƟ)" <Thomas.Sandlass@orthogon.com>
wrote:

> Mark Reed wrote: 
>> I would really like to see ($x div $y) be (floor($x/$y))
> 
> That is: floor( 8 / (-3) ) == floor( -2.6666.... ) == -3
> Or do you want -2?
> 
>> and ($x mod $y) be ($x - $x div $y).
> 
> Hmm, since 8 - (-3) == 11 this definition hardly works.

Sorry.  As you surmised, I left off a multiplication.
($x mod $y) should be ($x - $y * ($x div $y)).


> But even with $q = floor( $x / $y ) and $r = $x - $q * $y
> we get 8 - (-3) * (-3) == -1 where I guess you expect -2.

Why would I expect -2?  I don't actually have an preconceptions for negative
divisors.  But after just now taking a second to think about it, I would
expect it to generalize such that 0 <= abs($r) < abs($y), with sgn($r) in
{0, sgn($y)}.  So having (8 div -3) == -3 and (8 mod -3) == -1 works fine,
especially since it's consistent with (-8 div 3) == -3 and (-8 mod 3) == 1,
as given by my (corrected) formulae above.

> Looks like you want some case distinction there on the
> sign of $x. 

Absolutely not!  My entire goal is to avoid ever having to do something like
this:

    if ($x < 0) 
    {
        $y = formula1($x);
    }
    elsif ($x == 0)
    {
        $y = formula2($x);
    }
    else
    {
        $y = formula($x);
    }

At least, not in cases where the intended result is consistent across 0.
Lots of date arithmetic falls into this category, and works beautifully with
the definitions above.  It lets me do things without bounds checking and
correct the ranges later, because, e.g., plugging in January -20, 0 AD
yields the correct result for December 11, 2 BC.  Such calculations break
dramatically across 0 if you use the definition found in some C
implementations, where (-3 mod 5) == -3.

> If there is a definition that needs no special casing
> then it is the euclidean definition that 0 <= $r < abs $y.

In which case, for or your example of 8 == $q * (-3) + $r, $q == -2 and $r
== +2?  Seems odd to me that just swapping the signs (from -8,3 to 8,-3)
yields completely different numbers like that.




Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About