Re: mod/div

2005-06-06 Thread Roger Hale

Just a nit, for the record, with no great perl relevance:

"TSa (Thomas Sandlaß)" wrote:
But what is the first quarter of year 0? 0.25? 

Sure (of course if there were a year 0 instead of becoming 1 BCE)

> And the last quarter of year -1? -0.25?
Sure

> That works numerically, but March of a
year is then not always the same difference to the start of the year, 

but you seem to have changed the question (first quarter to last
quarter) but called both quarters March?

rather:
[>] And the _first_ quarter of year -1? -0.75?
Sure
[>] That works numerically, _and_ March of a
[>] year is then _ always the same difference to the start of the year,
(although it's the end of March and April Fool's Day (-04-01) that's
a quarter after New Year's Day.)

[> although written differently as a decimal substring; two's
> complement numbers with positive fractions do this better, being 0b.01
> in both cases.] paraphrasing


 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.

(Note that this recognizes that 0 CE == 1 BCE, and that January -20
brings you back into the previous December.)


Re: mod/div

2005-06-01 Thread TSa (Thomas Sandlaß)

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.9... 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ß)



Re: mod/div

2005-05-31 Thread Mark Reed
On 2005-05-30 05:15, "TSa (Thomas Sandlaß)" <[EMAIL PROTECTED]>
wrote:

> Mark Reed wrote: 
>> I would really like to see ($x div $y) be (floor($x/$y))
> 
> That is: floor( 8 / (-3) ) == floor( -2. ) == -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.





Re: mod/div

2005-05-30 Thread TSa (Thomas Sandlaß)

Mark Reed wrote:

I would really like to see ($x div $y) be (floor($x/$y))


That is: floor( 8 / (-3) ) == floor( -2. ) == -3
Or do you want -2?


and ($x mod $y) be ($x - $x div $y).


Hmm, since 8 - (-3) == 11 this definition hardly works.
But even with $q = floor( $x / $y ) and $r = $x - $q * $y
we get 8 - (-3) * (-3) == -1 where I guess you expect -2.
Looks like you want some case distinction there on the
sign of $x.



If the divisor is positive the modulus should be
positive, no matter what the sign of the dividend.


The problem is that with two numbers $x and $y you get
four combinations of signs which must be considered when
calculating $q and $r such that $x == $q * $y + $r holds.



Avoids lots of special case code across 0 boundaries.


If there is a definition that needs no special casing
then it is the euclidean definition that 0 <= $r < abs $y.
--
TSa (Thomas Sandlaß)



Re: mod/div (was: reduce metaoperator on an empty list)

2005-05-23 Thread Mark Reed
I would really like to see ($x div $y) be (floor($x/$y)) and ($x mod $y) be
($x - $x div $y).   If the divisor is positive the modulus should be
positive, no matter what the sign of the dividend.  Avoids lots of special
case code across 0 boundaries.


On 2005-05-23 18:49, "TSa (Thomas Sandlaß)" <[EMAIL PROTECTED]>
wrote:

> [EMAIL PROTECTED] wrote:
>> > There are actuall two usefull definition for %.  The first which Ada calls
>> 'mod' always returns a value 0<=X> an identity.  The other which Ada calls 'rem' defined as follows:
> 
>> > 
>> > Signed integer division and remainder are defined by the relation:
>> > 
>> > A = (A/B)*B + (A rem B)
>> > 
>> >where (A rem B) has the sign of A and an absolute value less than the
>> absolute value of B. Signed integer division satisfies the identity:
> 
>> > 
>> > (-A)/B = -(A/B) = A/(-B)
>> > 
>> > It does have a right side identity of +INF.
> 
> This is the truncating div-dominant definition of modulo.
> The eulerian definition is mod-dominant and nicely handles
> non-integer values. E.g.
> 
>   3.2 == 1.5 * 2 + 0.2 -+-->  3.2 / 1.5 == 2 + 0.2 / 1.5 == 2 + 1/15
> |   == 2 + 0.1333...
> +-->  3.2 % 1.5 == 0.2
> 
> Note that -3.2 == -4 + 0.8 == -4.5 + 1.3 == ...
> 
>-3.2 / 1.5 == -3 + 1.3 / 1.5 == -3 + 0.8666... == -2.1333
>-3.2 % 1.5 ==  1.3
> 
> With integers: 
> 
>   8  /   3  ==  (2 + 2/3) ==  2
>   8  / (-3) == -(2 + 2/3) == -2
> (-8) /   3  == -(3 - 1/3) == -3  # this might surprise some people ;)
> (-8) / (-3) ==  (3 - 1/3) ==  3
> 
>   8  % (-3) ==   8  % 3 == 2
> (-8) % (-3) == (-8) % 3 == 1  # this as well, but it's just -3 * 3 + 1
> 
> Real valued division can be considered as % 0, that is infinite precision.
> While integer arithmetic is % 1. I.e. int $x == $x - $x % 1.
> 
> floor $x == $x - $x % 1# -1.2 - (-1.2) % 1 == -1.2 - 0.8 == -2
> ceil  $x == 1 + floor $x
> round $x == floor( $x + 0.5 )
> trunc $x == $x < 0 ?? ceil $x :: floor $x
> 
> To @Larry: how are mod and div defined in Perl6?




mod/div (was: reduce metaoperator on an empty list)

2005-05-23 Thread TSa (Thomas Sandlaß)

[EMAIL PROTECTED] wrote:

There are actuall two usefull definition for %.  The first which Ada calls 'mod' 
always returns a value 0<=XSigned integer division and remainder are defined by the relation: 


A = (A/B)*B + (A rem B)

   where (A rem B) has the sign of A and an absolute value less than the absolute value of B. Signed integer division satisfies the identity: 


(-A)/B = -(A/B) = A/(-B)

It does have a right side identity of +INF.


This is the truncating div-dominant definition of modulo.
The eulerian definition is mod-dominant and nicely handles
non-integer values. E.g.

 3.2 == 1.5 * 2 + 0.2 -+-->  3.2 / 1.5 == 2 + 0.2 / 1.5 == 2 + 1/15
   |   == 2 + 0.1333...
   +-->  3.2 % 1.5 == 0.2

Note that -3.2 == -4 + 0.8 == -4.5 + 1.3 == ...

  -3.2 / 1.5 == -3 + 1.3 / 1.5 == -3 + 0.8666... == -2.1333
  -3.2 % 1.5 ==  1.3

With integers:

 8  /   3  ==  (2 + 2/3) ==  2
 8  / (-3) == -(2 + 2/3) == -2
   (-8) /   3  == -(3 - 1/3) == -3  # this might surprise some people ;)
   (-8) / (-3) ==  (3 - 1/3) ==  3

 8  % (-3) ==   8  % 3 == 2
   (-8) % (-3) == (-8) % 3 == 1  # this as well, but it's just -3 * 3 + 1

Real valued division can be considered as % 0, that is infinite precision.
While integer arithmetic is % 1. I.e. int $x == $x - $x % 1.

   floor $x == $x - $x % 1# -1.2 - (-1.2) % 1 == -1.2 - 0.8 == -2
   ceil  $x == 1 + floor $x
   round $x == floor( $x + 0.5 )
   trunc $x == $x < 0 ?? ceil $x :: floor $x

To @Larry: how are mod and div defined in Perl6?
--
TSa (Thomas Sandlaß)