[M3devel] integer division/mod questions?

Tony Hosking hosking at cs.purdue.edu
Wed Jan 20 11:07:45 CET 2010


These are all overflow examples correct?  In which case the meaning is undefined?

But certainly, 0 DIV -1 should be 0.

I haven't had a chance to diff the previous code with your new code, but in the long time the previous code was in place there had never been a complaint that DIV was buggy.  In the overflow cases surely we are allowed to go with whatever the hardware produces, so long as the code is efficient for non-overflow situations?  I suppose one thing to ensure is that the compile-time evaluation (TInt) and the run-time evaluations are consistent, otherwise there will be confusion.

On 19 Jan 2010, at 21:45, Jay K wrote:

> 
>> There is a positive zero and a negative zero, and which one you get 
> 
> 
> Rodney you reminded me of something I forgot to ask: 
> 
> 
> Is 0 div -1 = 0 or -1?
> 
> 
> In particular, in floating point, 0 / -1 is presumably -0 and 0 / 1 is presumably +0. Modula-3 is specified as returning the largest integer not greater than the floating point result. So the question then is, is 0> -0? Or are they equal? Integer-wise, there is no -0.
> If 0> -0, then 0 div -1 should equal -1 instead of 0.
> 
> 
> My current code I believe returns 0 for 0 div anything.
>  And I believe "the mod formula" holds as correct, since my testing checks that. I'll have to double double check.
> 
> 
> The previous code probably also but I'll have to double check.
>  The previous code isn't necessarily the definition of correct though, since it was pretty clearly wrong for some cases.
> 
> 
>  Which is imply the question: Everyone agrees with me that the previous code was wrong? In particular, for LONG_MIN div negative, it was giving negative results, but I believe the result should be positive. Mod had a similar problem.
> 
> 
>  Nice if anyone can reproduce the problem with K&R + long long as well.
>  I don't like making changes here without some kind of independent confirmation, though I'm also pretty sure of myself..a contradiction I realize.
> 
> 
>  The previous code and I believe the current code are inconsistent as to when it would "trap", depending on compiler and optimization level. I assume that is ok for now, though in future we might want to make it predictable and honor the FloatMode stuff, but until that time, "unpredictable" is ok.
> 
> 
>  In particular, LONG_MIN div or mod -1 can trap.
> 
> 
>  div clearly has little choice. Mod I have to think about -- mod should be zero, right? LONG_MIN "evenly" divides by -1, the answer can't be represented, but the remainder can (it is zero). So maybe we should special case that to ensure it doesn't trap.
> 
> 
> (anywhere I say "LONG_MIN", INT64_MIN has similar problem)
> 
> 
> 
> - Jay
> 
> 
> ----------------------------------------
>> Date: Tue, 19 Jan 2010 18:39:22 -0600
>> From: rodney_bates at lcwb.coop
>> To: m3devel at elegosoft.com
>> Subject: Re: [M3devel] integer division/mod questions?
>> 
>> 
>> 
>> hendrik at topoi.pooq.com wrote:
>>> On Sun, Jan 17, 2010 at 10:44:53AM +0000, Jay K wrote:
>>>> -2147483648 div 2147483647 ?
>>>> -2147483648 mod 2147483647 ?
>>>> 
>>>> quotient = -1, remainer = -1 seems reasonable.
>>>> 2147483647 * -1 + -1 == -2147483648
>>>> 
>>> 
>>> There are two kinds of binary integer arithmetic -- two's complement
>>> and one's complement. In my experience, two's complement machines tend
>>> to have the remainder being the same sign as the dividend; one's
>>> complement machines semm to have a remainder the same sign as the
>>> divisor.
>>> 
>>> One's complement machines are all but extinct these days.
>> 
>> Tony, you were concerned about showing your age, but 20 years is but an
>> evening past. I remember programming ones-complement arithmetic
>> in assembly language, definitely more decades ago than two.
>> And that was not my first job.
>> 
>> There is a positive zero and a negative zero, and which one you get
>> can depend on the operation and operand values that produced the
>> result, so you have to check for both of them, often with two
>> separate conditional branches.
>> 
>> Anyone remember nines- or tens-complement arithmetic on decimal
>> machines? Electromechanical accounting machines?
>> 
>> 
>>> 
>>>> However, Modula-3 specifies div as rounding down, so
>>>> 
>>>> -2147483648 div 2147483647 == -2
>>>> 
>>>> and then
>>>> 
>>>> http://www.modula3.com/cm3/doc/reference/arithmetic.html
>>>> 
>>>> The value x DIV y is the floor of
>>>> the quotient of x and y; that is, the maximum integer
>>>> not exceeding the real number z such that z * y = x.
>>>> For integers x and y, the value of x MOD y is
>>>> defined to be x - y * (x DIV y).
>>>> 
>>>> 
>>>> This means that for positive y, the value of x MOD y
>>>> lies in the interval [0 .. y-1], regardless of
>>>> the sign of x. For negative y, the value of
>>>> x MOD y lies in the interval [y+1 .. 0], regardless
>>>> of the sign of x.
>>> 
>>> And this is consistent with MOD producing a canonical representative of
>>> an equivalence class modulo y. It's what's wanted for a lot of
>>> algorithms. What it returns for negative y isn't as important, but
>>> it is important to have positive MODuli for positive y no matter what
>>> the sign of x is.
>>> 
>>> But it's not what most two's-complement processors produce naturally.
>>> Having a MODulo operation that is mathematically well-behaved takes
>>> extra effort on these machines.
>>> 
>>> And it's also important to have a remainder that corresponds to the
>>> division operator. On two's complement machines you have to either
>>> * use extra instructions to correct the result of the divide
>>> instruction to correspond to the mathematically desirable MOD
>>> operator, or
>>> * Have a separate remainder operation that does correspond to
>>> division.
>>> 
>>> On one's complement machines MOD will have the same effect as remainder.
>>> On two's complement, different.
>>> 
>>> -- hendrik
>>> 		 	   		  




More information about the M3devel mailing list