Re: mod/div
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
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
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
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)
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)
[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ß)