# Board index » delphi » Newbie with MOD question

## Newbie with MOD question

Trying to make sense of MOD.  I cannot find a pattern to when the result
of a mod operation is negative vs positive.  It does not seem to follow
the rules of division, ie:   "Odd number of negative signs = odd answer,
Even number of negative signs = Even answer."

Integer results produced by Pascal:

-23 div -4 = 5       (Positive result is expected per rule quoted above)
-23 mod -4 = -3    (Negative result unexpected)

Can anyone tell me what the rule is for when mod will produce a negative
result, and when mod will produce a positive?

Thanks!

## Re:Newbie with MOD question

##### Quote
HyFolks (hyfo...@aol.com) wrote:
> Trying to make sense of MOD.  I cannot find a pattern to when the result
> of a mod operation is negative vs positive.  It does not seem to follow
> the rules of division, ie:   "Odd number of negative signs = odd answer,
> Even number of negative signs = Even answer."
> Integer results produced by Pascal:
> -23 div -4 = 5       (Positive result is expected per rule quoted above)
> -23 mod -4 = -3    (Negative result unexpected)
> Can anyone tell me what the rule is for when mod will produce a negative
> result, and when mod will produce a positive?
> Thanks!

Borland's implementations of MOD and DIV have never worked the way they
ought to with negative numbers.  As far as I can tell, the dude who coded
the routines simply stripped out the signs to make the arguments positive
and then just snuck a minus sign back in at the end.  I've always been
leery of passing negative arguments to DIV and MOD.

BTW what do you think you mean by mod -4?

David Emanuel

## Re:Newbie with MOD question

##### Quote
hyfo...@aol.com (HyFolks) writes:
>Trying to make sense of MOD.  I cannot find a pattern to when the result
>of a mod operation is negative vs positive.  It does not seem to follow
>the rules of division, ie:   "Odd number of negative signs = odd answer,
>Even number of negative signs = Even answer."
>Integer results produced by Pascal:
>-23 div -4 = 5       (Positive result is expected per rule quoted above)
>-23 mod -4 = -3    (Negative result unexpected)

a mod b = a - ( a div b) * b

Thus the example gives -23 - (-20) which is -3.

## Re:Newbie with MOD question

##### Quote
In article <42sjbi\$...@newsbf02.news.aol.com> hyfo...@aol.com "HyFolks" writes:
> Trying to make sense of MOD.  I cannot find a pattern to when the result
> of a mod operation is negative vs positive.  It does not seem to follow
> the rules of division, ie:   "Odd number of negative signs = odd answer,
> Even number of negative signs = Even answer."

> Integer results produced by Pascal:

> -23 div -4 = 5       (Positive result is expected per rule quoted above)
> -23 mod -4 = -3    (Negative result unexpected)

This does, however, follow the rule of mod and div:

y * (x div y) + (x mod y) = x

--
Tom Wheeley

## Re:Newbie with MOD question

##### Quote
In article <42sjbi\$...@newsbf02.news.aol.com>, hyfo...@aol.com (HyFolks) writes:
>Trying to make sense of MOD.  I cannot find a pattern to when the result
>of a mod operation is negative vs positive.  It does not seem to follow
>the rules of division, ie:   "Odd number of negative signs = odd answer,
>Even number of negative signs = Even answer."

>Integer results produced by Pascal:

>-23 div -4 = 5       (Positive result is expected per rule quoted above)
>-23 mod -4 = -3    (Negative result unexpected)

>Can anyone tell me what the rule is for when mod will produce a negative
>result, and when mod will produce a positive?

The mod operator was intended to be an arithmetic "remainder" operator,
such that (( a div b ) * b ) + ( a mod b ) should = a.

According to
Jensen, Kathleen & Wirth, Niklaus (1974).  _Pascal User Manual and
Report_.  New York: Springer-Verlag.  ISBN: 0-387-90144-2.
the definition of the mod operator is:
a mod b  =  a - (( a div b ) * b)

which satisfies that intention and your example.

##### Quote

>Thanks!

HTH

-* Stephen *-
Stephen Posey
University of New Orleans
Email  : S...@uno.edu
WWW    : http://www.uno.edu/~slp

## Re:Newbie with MOD question

The MOD operator was, I believe, defined only for positive right
arguments.  The idea is that it is a "mapping" of the integers into a subset
of integers from 0 .. m-1 (where "m" is the right operand, the "modulus").
Thus this can give you the pixel column, given the width of the screen, as
"pixel MOD width" (with the row being "pixel DIV width").  The extension to
negative left arguments is designed to admit the same mapping, namely from 0
to m-1.  So, for another example, if you number months as 0 .. 11 (jan ..
dec), then to get the previous month you'd do "pred(month) MOD 12", and would
find december precedes january.

Bob Schor
Pascal Enthusiast

## Re:Newbie with MOD question

##### Quote
On Mon, 11 Sep 1995, Bob Schor wrote:
>      The MOD operator was, I believe, defined only for positive right
> arguments.  The idea is that it is a "mapping" of the integers into a subset
> of integers from 0 .. m-1 (where "m" is the right operand, the "modulus").
> Thus this can give you the pixel column, given the width of the screen, as
> "pixel MOD width" (with the row being "pixel DIV width").  The extension to
> negative left arguments is designed to admit the same mapping, namely from 0
> to m-1.  So, for another example, if you number months as 0 .. 11 (jan ..
> dec), then to get the previous month you'd do "pred(month) MOD 12", and would
> find december precedes january.

No, 'coz it would be negative February that precedes January like that.
:)  To find the predecessor of a month, the fastest way would probably be
"(month + 11) mod 12".  Of course, you could do the lame way:

newmonth := pred(month) mod 12;
while newmonth < 0 do
inc (newmonth, 12);

but that adds in many needless instructions... of course, it's more
understandable and if you're writing a Windows application, it's not
going to matter whether you code clean or not, since as we all know, under
Windows it latches the timer interrupt to the following:

mov cx, 65535d
rep nop

:)

That's why on slower computers it crashes (as it tries to call the timer
interrupt while it's still executing :)

-----------------\------------------------------------------------------------
Quantum Porcupine \-\  People kept on telling me to get on with it and write
a.k.a. Joshua Shagam > my damn .sig file.  Well I finally got around to it
jsha...@nmsu.edu /--/  since I finally got SIG of it all.
----------------/-------------------------------------------------------------

## Re:Newbie with MOD question

##### Quote
>On Mon, 11 Sep 1995, Bob Schor wrote:
>>      The MOD operator was, I believe, defined only for positive right
>> arguments.  The idea is that it is a "mapping" of the integers into a subset
>> of integers from 0 .. m-1 (where "m" is the right operand, the "modulus").
>> Thus this can give you the pixel column, given the width of the screen, as
>> "pixel MOD width" (with the row being "pixel DIV width").  The extension to
>> negative left arguments is designed to admit the same mapping, namely from 0
>> to m-1.  So, for another example, if you number months as 0 .. 11 (jan ..
>> dec), then to get the previous month you'd do "pred(month) MOD 12", and would
>> find december precedes january.

>No, 'coz it would be negative February that precedes January like that.
>:)  To find the predecessor of a month, the fastest way would probably be
>"(month + 11) mod 12".

Sigh.  While I was correct "in theory", I was wrong in practice.  Even my
non-Borland compiler said that -1 mod 12 was -1, not 11 (as I had assumed).

Still, the goal of this exercise is to make code readable and
understandable.  Let's assume that MOD returns values between -modulus and
+modulus, and we want the "logically-correct" MOD function I thought I had.
Simply do the MOD operation, test if negative, and if so, make positive by

So my previous example becomes

IF (prev(month) MOD 12) < 0
THEN precedingmonth := 12 + prev(month) MOD 12
ELSE precedingmonth := prev(month) MOD 12;

[I know this requires more than one evaluation of prev(month) MOD 12, but has
the benefit that if precedingmonth is defined as [0 .. 11], the above code
will never give a run-time error, he said optimistically].

Bob Schor
Pascal Enthusiast

[I'm a great believer that code should be "intuitively understandable" by most
readers -- it is up to the computer and compiler writers to make them fast,
but up to the human programmer to make them correct.]

## Re:Newbie with MOD question

##### Quote
In article <bschor.242.1E3C4...@vms.cis.pitt.edu> bsc...@vms.cis.pitt.edu (Bob Schor) writes:
>From: bsc...@vms.cis.pitt.edu (Bob Schor)
>>On Mon, 11 Sep 1995, Bob Schor wrote:
>>>      The MOD operator was, I believe, defined only for positive right
>>> arguments.
>>..
>Bob Schor
>Pascal Enthusiast

There is a need for two operators, say modd & divv, to be well-known standards
with the property that, if one plots (x modd y) and (x divv y) against x for
x=-2y step 1 to 2y, one cannot see by inspection of the line where x=0 is.
Mod & div do not AFAIR do this. Likewise there should be standard operators
for trunc-towards-0 and trunc-negativewards (& trunc-positivewards?).  By
standards I mean that they should be in the usual libraries available to all,
and so well-known to users.
--
John Stockton : mailto:J...@dclf.npl.co.uk from off-site.  MIME.  WP.
National Physical Laboratory, Teddington, Middlesex, TW11 0LW, UK
Direct Phone +44 181-943 6087, Nearby Fax +44 181-943 7138
Postings out, Email in/out are fast.  Offshore news takes 0..10+
days to arrive; please mail me a copy of non-UK followups!
Regret system puts unzoned (UK civil) time on messages.

## Re:Newbie with MOD question

##### Quote
On Wed, 13 Sep 1995, Bob Schor wrote:
> >On Mon, 11 Sep 1995, Bob Schor wrote:

> >>      The MOD operator was, I believe, defined only for positive right
> >> arguments.  The idea is that it is a "mapping" of the integers into a subset
> >> of integers from 0 .. m-1 (where "m" is the right operand, the "modulus").
> >> Thus this can give you the pixel column, given the width of the screen, as
> >> "pixel MOD width" (with the row being "pixel DIV width").  The extension to
> >> negative left arguments is designed to admit the same mapping, namely from 0
> >> to m-1.  So, for another example, if you number months as 0 .. 11 (jan ..
> >> dec), then to get the previous month you'd do "pred(month) MOD 12", and would
> >> find december precedes january.

> >No, 'coz it would be negative February that precedes January like that.
> >:)  To find the predecessor of a month, the fastest way would probably be
> >"(month + 11) mod 12".

> Sigh.  While I was correct "in theory", I was wrong in practice.  Even my
> non-Borland compiler said that -1 mod 12 was -1, not 11 (as I had assumed).

>      Still, the goal of this exercise is to make code readable and
> understandable.  Let's assume that MOD returns values between -modulus and
> +modulus, and we want the "logically-correct" MOD function I thought I had.
> Simply do the MOD operation, test if negative, and if so, make positive by
> adding back in the modulus.

>      So my previous example becomes

>      IF (prev(month) MOD 12) < 0
>       THEN precedingmonth := 12 + prev(month) MOD 12
>        ELSE precedingmonth := prev(month) MOD 12;

Sorry, but this would be easier with:

precedingmonth := pred(month) mod 12;
while precedingmonth < 0 do
inc (precedingmonth, 12);

I just had to respond, since it's a little more logical, a LOT cleaner,
and takes only one div in the compiled code (rather than 3).

##### Quote
> [I know this requires more than one evaluation of prev(month) MOD 12, but has
> the benefit that if precedingmonth is defined as [0 .. 11], the above code
> will never give a run-time error, he said optimistically].

Neither would mine. :)

##### Quote
> [I'm a great believer that code should be "intuitively understandable" by most
> readers -- it is up to the computer and compiler writers to make them fast,
> but up to the human programmer to make them correct.]

Good point there... this is kind of like that shl cx, 33d which I was
plagued with awhile back... :)

-----------------\------------------------------------------------------------
Quantum Porcupine \-\  People kept on telling me to get on with it and write
a.k.a. Joshua Shagam > my damn .sig file.  Well I finally got around to it
jsha...@nmsu.edu /--/  since I finally got SIG of it all.
----------------/-------------------------------------------------------------