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

Re: mod/div

Thread Previous | Thread Next
From:
=?ISO-8859-1?Q?=22TSa_=28Thomas_Sandla=DF=29=22?=
Date:
June 1, 2005 06:53
Subject:
Re: mod/div
Message ID:
429DBDB5.70404@orthogon.com
Mark Reed wrote:
> 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.

Does it? If you have a year 0, what is the number corresponding
to the middle of that year? Is it 0.5? Is than 1.5 the middle of
year one? Where is the middle of year -1? -1.5? Or -0.5? With the
middles as -0.5 and 0.5 you get at least a time difference of one
year. But what is the first quarter of year 0? 0.25? And the last
quarter of year -1? -0.25? That works numerically, but March of a
year is then not always the same difference to the start of the year, 
actually this is where you have to make the case destinction on
the sign of the year to add or substract 1 in the fractional part
of a sub-year units. Two's complement integers and positive remainders
give that automatically.

BTW, the above arithmetic very nicely fits the string positions
depending on Unicode level. Position 0 is before the first character
of the string, the position n is after a string of length n. Positions
of lower levels are positive fractions into the higher level character.
An empty string has start == end.


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

Ahh yes, the C definition doesn't fulfill the Division Rule. Neither
does the Perl 5 pair of int() and %. But I hope the latter is corrected
for Perl 6? Does someone know which code depends on that unfortunate
behaviour? Note that all definitions give the same results for positive
dividend and divisor.


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

Sorry, you are changing the numbers you divide and wonder that the results
are different? Don't be fooled by the usual number denotations which
are asymetric around the Origin: +2.3 is (+2 + 0.3) while -2.3 is
(-2 + -0.3). This is expressed in words as "2.3 is 0.3 after 2" and
"-2.3 is 0.3 before -2". While a two's complement interpretation would
keep the remainder always positive because it is in ascending direction
into the intervall spanned by the integer part and its successor. 
Unfortunately only few people know about the interpretation -2.3 as
(-2 + 0.3) which reads "-2.3 is 0.3 after -2". This can be generalised
to "$x is {$x mod 1} after {$x div 1}".

Here are ASCII charts of these two functions, with * indicating the jumps.
A divisor d determines the distance abs(d) between the jumps of (x div d)
and zeros of (x mod d). For d < 0 the intervall 0 <= x < abs(d) remains 0
and all others flip sides of the x axes as expected. Note that ifinite
precision can be interpreted as arithmetik modulo 0, not Infinity. Thus
the remainder is always 0, and the div function is the 45 degree line
through the origin, which is equivalent to the definition of the 
multiplicative inverse x * y == 1 and of course y = 1/x for x != 0.
And as many people know these are hyperbolas through (1,1) and (-1,-1)
respectively and I stop ranting ...

                |
               3+           *===
                |
               2+       *===
                |
               1+   *===
                |
---|---|---|---*===|---|---|---->
   -3  -2  -1   0   1   2   3
            *===+-1
                |
        *===    +-2
                |
    *===        +-3
                |



                |
                +abs(d)
       /   /   /|  /   /   /   /
      /   /   / | /   /   /   /
     /   /   /  |/   /   /   /
---*---*---*---*---*---*---*---->
                0     ->|   |<-
                |       abs(d)


The euclidean definition nicely produces the two's complement! And it
allows negative-digit, negative-radix number representations without
case distinction.

Let's take clock arithmetic which is---you guessed it---modulo -12.
Thus 11 + 2 == 1 because of 13 == (-1) * (-12) + 1. Note that the string
'12' is the zero digit because 12 == (0) * (-12) + 12. "A quarter past
midnight" is just -12 + 0.25 while "a quarter past noon" is 0 + .25.
So the 24 hour day goes from -12.0 to +11.99999... that is +12 is the -12
of the next day. And 0.0 is noon. And of course the clock is rotating in
mathematically negative direction :)

I just see arithmetic regularity.
-- 
TSa (Thomas SandlaƟ)


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