[comp.lang.c] % operator with negatives

t901908@mp.cs.niu.edu (Joe Adamo) (12/13/90)

I know this may sound silly, but what is the effect of using the 
% (mod) operator with negatives?  I can't seem to find any info on it.

Thanks in advance,

Joe Adamo

**Northern Illinois University, a nice place to visit but.... 

gwyn@smoke.brl.mil (Doug Gwyn) (12/13/90)

In article <1990Dec12.185714.7169@mp.cs.niu.edu> t901908@mp.cs.niu.edu (Joe Adamo) writes:
>I know this may sound silly, but what is the effect of using the 
>% (mod) operator with negatives?  I can't seem to find any info on it.

Two things:  % is NOT a modulo operator; it's a remainder operator, which
is not the same thing.  Also, for negative operands there are implementation-
dependent aspects to the result obtained; in most applications you should
avoid using negative operands.

henry@zoo.toronto.edu (Henry Spencer) (12/13/90)

In article <1990Dec12.185714.7169@mp.cs.niu.edu> t901908@mp.cs.niu.edu (Joe Adamo) writes:
>I know this may sound silly, but what is the effect of using the 
>% (mod) operator with negatives?  I can't seem to find any info on it.

If you're asking the obvious question -- "what's the sign of the remainder?",
i.e. "which way does the rounding of the quotient go?" -- there is no
portable answer.  It's implementation-specific.
-- 
"The average pointer, statistically,    |Henry Spencer at U of Toronto Zoology
points somewhere in X." -Hugh Redelmeier| henry@zoo.toronto.edu   utzoo!henry

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (12/13/90)

In article <1990Dec12.205416.26622@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
> In article <1990Dec12.185714.7169@mp.cs.niu.edu> t901908@mp.cs.niu.edu (Joe Adamo) writes:
> >I know this may sound silly, but what is the effect of using the 
> >% (mod) operator with negatives?  I can't seem to find any info on it.
> If you're asking the obvious question -- "what's the sign of the remainder?",
> i.e. "which way does the rounding of the quotient go?" -- there is no
> portable answer.  It's implementation-specific.

And if you're asking ``Where is the information on it?'', the answer is
that a % b is defined so that (a / b) * b + (a % b) equals a. It's the
ambiguous definition of / that makes % so useless with negatives.

---Dan

rmc@nixtdc.uucp (Russell Crook) (12/13/90)

Even more disturbing about the / ambiguity... 
If I interpret the ANSI standard correctly, there is no guarantee that
   (-a)/b == a/(-b)
where a and b are positive (e.g., 14 and 10).
It appears to be legal for the rounding direction to vary arbitrarily
even on one machine when / and negative numbers are involved.
Yecch.

It would have been nice to have / more tightly defined, but (alas)
reality intrudes.
We have to work with several systems, and the preferred
rounding direction does indeed vary between them.
And yes, we got bitten by it :-< :-< .

-- 
------------------------------------------------------------------------------
Russell Crook, Siemens Nixdorf Information Systems, Toronto Development Centre
2235 Sheppard Ave. E., Willowdale, Ontario, Canada M2J 5B5
Ph: +1 416 496 8510      Fax: +1 416 496 8534

brandis@inf.ethz.ch (Marc Brandis) (12/14/90)

In article <7461:Dec1310:04:0990@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>In article <1990Dec12.205416.26622@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
>> In article <1990Dec12.185714.7169@mp.cs.niu.edu> t901908@mp.cs.niu.edu (Joe Adamo) writes:
>> >I know this may sound silly, but what is the effect of using the 
>> >% (mod) operator with negatives?  I can't seem to find any info on it.
>> If you're asking the obvious question -- "what's the sign of the remainder?",
>> i.e. "which way does the rounding of the quotient go?" -- there is no
>> portable answer.  It's implementation-specific.
>
>And if you're asking ``Where is the information on it?'', the answer is
>that a % b is defined so that (a / b) * b + (a % b) equals a. It's the
>ambiguous definition of / that makes % so useless with negatives.
>
Did somebody ever try it on the VAX? A guy told me once that integer division
rounds toward zero on the VAX while the MOD instruction delivers always a
positive result, which does not fulfill the above equation. Or does the VAX
have a separate REM instruction? At least for Pascal it is completely wrong.


Marc-Michael Brandis
Computer Systems Laboratory, ETH-Zentrum (Swiss Federal Institute of Technology)
CH-8092 Zurich, Switzerland
email: brandis@inf.ethz.ch

drack@titan.tsd.arlut.utexas.edu (Dave Rackley) (12/14/90)

   In article <1990Dec12.185714.7169@mp.cs.niu.edu> t901908@mp.cs.niu.edu (Joe Adamo) writes:

   >>I know this may sound silly, but what is the effect of using the 
   >>% (mod) operator with negatives?  I can't seem to find any info on it.

In article <14722@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes:

   >Two things:  % is NOT a modulo operator; it's a remainder operator, which
   >is not the same thing.  Also, for negative operands there are 
   >implementation-dependent aspects to the result obtained; in most 
   >applications you should avoid using negative operands.

Hmmm?  You answer is correct, except _K & R 2d edition_, page 41, refers to 
 % as the modulus operator.  Prentice Hall must have missed it during
their review.  I agree, one should avoid negative operands with %.

--

  DISCLAIMER?  I don't know anything 'bout any ol' disclaimer!         

+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+
| David Rackley		        |                                             |
| Applied Research Laboratories |      It's OK to be a martyr, as long as     |
| The University of Texas       |      you don't bring your own firewood.     |
| Austin, TX.  78758            |                          -- Dr. James Rigby |
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=+

karl@ima.isc.com (Karl Heuer) (12/14/90)

In article <18140@neptune.inf.ethz.ch> brandis@inf.ethz.ch (Marc Brandis) writes:
>Did somebody ever try it on the VAX? A guy told me once that integer division
>rounds toward zero on the VAX while the MOD instruction delivers always a
>positive result...

Sounds like you're refering to what the Pascal compiler does, rather than
the machine language.  When I first encountered the VAX, one of my first
complaints was that it didn't *have* a 32-bit MOD instruction (or
equivalently, a DIV that generated remainder as well as quotient).  The
compiler must either generate a-(a/b)*b, or extend a into a double word% and
use the 64-bit EDIV (which *does* generate both quotient and remainder).

Karl W. Z. Heuer (karl@ima.isc.com or uunet!ima!karl), The Walking Lint
% DEC, out of loyalty to their 16-bit line, called their halfwords `words'
  and so they called this thing a `quadword'.

kevin@math.lsa.umich.edu (Kevin Coombes) (12/14/90)

f you know what types you're working with and you're worried about what
happens with negatives, you can always use the following function, which
is guaranteed to return an answer between 0 and p-1.

int
safemod(int a, int p)
{
  if (a < 0)
    return p - ((-a) % p);
  else
    return a % p;
}

Best,
Kevin <krc@mayme.umd.edu>

scott@bbxsda.UUCP (Scott Amspoker) (12/15/90)

In article <7461:Dec1310:04:0990@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>And if you're asking ``Where is the information on it?'', the answer is
>that a % b is defined so that (a / b) * b + (a % b) equals a. It's the
>ambiguous definition of / that makes % so useless with negatives.

Well I can really stir up the muck by pointing out that, by definition,

    a mod 0 == a

Therefore, the method of dividing (a/b) does not always work since b could 
legally equal 0.  To be fair, C compilers disregard this "feature" of a
modulo and give an error on expressions such as 'a % 0'.  If you wish
a guaranteed proper modulo you might have to implement your own and
not rely on the '%' operater.

-- 
Scott Amspoker                       |
Basis International, Albuquerque, NM | "I'm going out for a sandwich"
(505) 345-5232                       |                       - Ben
unmvax.cs.unm.edu!bbx!bbxsda!scott   |

steve@taumet.com (Stephen Clamage) (12/16/90)

scott@bbxsda.UUCP (Scott Amspoker) writes:

>Well I can really stir up the muck by pointing out that, by definition,

>    a mod 0 == a

>Therefore, the method of dividing (a/b) does not always work since b could 
>legally equal 0.

As has been pointed out before the "%" operator in C is NOT a mod 
operator, but a remainder operator.  As such it is defined in terms
of division; thus a%0 is undefined.  (The ANSI standard explicitly
says that a%0 is undefined.)
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (12/17/90)

In article <1990Dec14.153706.14688@math.lsa.umich.edu> kevin@math.lsa.umich.edu (Kevin Coombes) writes:
> f you know what types you're working with and you're worried about what
> happens with negatives, you can always use the following function, which
> is guaranteed to return an answer between 0 and p-1.

No, it is not. If, for instance, a is -p and p is positive, your
function will return p.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (12/17/90)

In article <1529@bbxsda.UUCP> scott@bbxsda.UUCP (Scott Amspoker) writes:
> In article <7461:Dec1310:04:0990@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
> >And if you're asking ``Where is the information on it?'', the answer is
> >that a % b is defined so that (a / b) * b + (a % b) equals a. It's the
> >ambiguous definition of / that makes % so useless with negatives.
> Well I can really stir up the muck by pointing out that, by definition,
>     a mod 0 == a

We are (unfortunately) not talking about the mathematical mod function.
We are talking about the C % function.

I have never seen a sane use of remainders outside [0,b), b positive.
I have never seen a program use remainders for b negative. It's a shame
that no popular programming language has a mod function defined only for
b positive and guaranteed to be between 0 and b - 1 inclusive, as this
would strike the right balance between portability and efficiency.

---Dan

bks@alfa.berkeley.edu (Brad Sherman) (12/18/90)

--Quite distinct from the "%" is [not] a modulus operator discussion--.

For those wishing to implement a modulous function that behaves in 
a reasonable manner for all integers I offer the following notes
taken from a book by Knuth and others (title forgotten).

	To make "m mod n" well defined for any integer value, positive
	or negative start from the relation:
		m = n * floor(m/n) + m mod n
	producing:
		m mod n = m - n * floor(m/n)
	e.g.:
		 5 mod  3 =  5 -   3  * floor( 5 /  3 ) =  5 -   3  *   1  =  2
		-5 mod  3 = -5 -   3  * floor(-5 /  3 ) = -5 -   3  * (-2) =  1
		 5 mod -3 =  5 - (-3) * floor( 5 /(-3)) =  5 - (-3) * (-2) = -1
		-5 mod -3 = -5 - (-3) * floor(-5 /(-3)) = -5 - (-3) *   1  = -2

	Note that the result always matches the modulus in sign.  No
	no one has ever come up with a good name for "m" and they
	suggest (with no smiley in the text!) "modumor."

[Errors in the above are mine, not Knuth's, I'm sure.]
---------------------------------
	Brad Sherman (bks@alfa.berkeley.edu)
	"Mathematics is the queen of the sciences and number theory
	the queen of mathematics." -- C.F. Gauss

jimc@gold.gvg.tek.com (Jim Chargin) (12/18/90)

In article <1990Dec17.175010.12654@agate.berkeley.edu>, bks@alfa.berkeley.edu (Brad Sherman) writes:

> For those wishing to implement a modulous function that behaves in 
> a reasonable manner for all integers I offer the following notes
> taken from a book by Knuth and others (title forgotten).
> 
> 	To make "m mod n" well defined for any integer value, positive
> 	or negative start from the relation:
>	. . .

I believe the book referred to is:

    Concrete Mathematics: a foundation for computer science
    Ronald L. Graham, Donald E. Knuth, Gren Patashnik
    Addison Wesley, 1989
    ISBN 0-201-14236-8


Jim

eager@ringworld.Eng.Sun.COM (Michael J. Eager) (12/19/90)

In article <1990Dec12.185714.7169@mp.cs.niu.edu> t901908@mp.cs.niu.edu (Joe Adamo) writes:
>I know this may sound silly, but what is the effect of using the 
>% (mod) operator with negatives?  I can't seem to find any info on it.


There are two well accepted definitions of the remainder of a division
when one of the arguments is zero.  One of the definitions has the remainder
be negative, the other positive.  The ANSI Standard does not specify
which definition applies. The only guarantee is that when you have

	q = d / n;  r = d % n;
that
	d == (q * n + r)


Best advice is to not use the % operator with negative values.

-- Mike Eager