3

This seems to be the #1 thing that is asked when dealing with Remainder/Mod, and I'm kind of hitting a wall with it. I'm teaching myself to program with a textbook and a chuck of C code.

Seeing as I don't really have an instructor to say, "No, no. It actually works like this", I thought I'd try my hand here. I haven't found a conclusive answer to the mathematical part of this, though.

So... I'm under the impression that this is a pretty rare occurrence, but I'd still like to know what it is that happens underneath the shiny compiling. Plus, this textbook would like for me to supply all values that are possible when using negative remainders, per the C89 Standard. Would it be much to ask if someone could check to see if this math is sound?

1) 9%4
9 - (2) * 4 = 1     //this is a value based on x - (x/y) * y
(2) * 4 + (1) = 9     //this is a check based on (x/y) * y + (x%y) = x

2) -9%4
9 - (2) * 4 = 1; 9 - (3) * 4 = -3   //these are the possible values
(2) * 4 + (1) = 9; (3) * 4 + (-3) = 9    //these are the checks

3) 9%-4
Same values as #2?? 

I tried computing with negatives in the expressions, and came up with ridiculous things such as 17 and -33. Are they 1 and -3 for #3 as well??

4) -9%-4
Same as #1??

In algebraic division, negative signs "cancel". Do they do the same here, or is there something else going on?

I think the thing that gets me confused the most is the negatives. The way I learned algebra in school (5-6 years ago), they are "attached" to their numbers. In programming, since they are unary operators, is that not so? Example: When filling in the value for x on #2, x = 9 instead of x = -9.

I sincerely appreciate any help.

  • 3
    Is this question helpful: http://stackoverflow.com/questions/8318791/is-there-a-reason-some-languages-allow-a-negative-modulus?rq=1 – Barmar Sep 14 '13 at 04:54
  • @Barmar thats a good link, sir. The discussion is actually civil and the points interesting. – WhozCraig Sep 14 '13 at 05:12
  • It is not clear how you could obtain -33 or 17 from remainder operations on any combination of positive and negative 9 and 4. You should show a [short, self-contained, compilable example](http://sscce.org/). – Eric Postpischil Sep 14 '13 at 12:06
  • @Eric Postpischil, those numbers were reached by trying to compute the remainders with long-hand, using -9 and -4 where applicable in the formulas above. There is no code to go along with them, just number-crunching for the sake of seeing what is going on. – SilvariaKiralv Sep 14 '13 at 15:10
  • I was also directed to this from a friend outside of Stack, and it may help anyone who finds themselves here. http://mathforum.org/library/drmath/view/52343.html – SilvariaKiralv Sep 14 '13 at 15:44

2 Answers2

4

Here you need the mathematical definition on remainder.

Given two integer numbers m, d, we say that r is the remainder of the division of m and d if r satisfies two conditions:

  • There exists another integer k such that m == k * d + r , and
  • 0 <= r < d.

For positive numbers, in C, we have m % d == r and m / d == k, just by following the definition above.

From the definition, it can be obtainded that 3 % 2 == 1 and 3 / 2 == 1.
Other examples:

4 / 3 == 1 and 5 / 3 == 1, in despite of 5.0/3.0 == 1.6666 (which would round to 2.0).

4 % 3 == 1 and 5 % 3 == 2.

You can trust also in the formula r = m - k * d, which in C is written as:

m % d == m - (m / d) * d

However, in the standard C, the integer division follows the rule: round to 0.
Thus, with negative operands C offer different results that the mathematical ones.
We would have:

(-4) / 3 == -1, (-4) % 3 == -1 (in C), but in plain maths: (-4) / 3 = -2, (-4) % 3 = 2.

In plain maths, the remainder is always nonnegative, and less than the abs(d).
In standard C, the remainder always has the sign of the first operand.

 +-----------------------+
 |  m  |  d  |  /  |  %  |
 +-----+-----+-----+-----+
 |  4  |  3  |  1  |  1  |
 +-----+-----+-----+-----+
 | -4  |  3  | -1  | -1  |
 +-----+-----+-----+-----+
 |  4  | -3  | -1  |  1  |
 +-----+-----+-----+-----+
 | -4  | -3  |  1  | -1  |
 +-----------------------+

Remark: This description (in the negative case) is for standard C99/C11 only. You must be carefull with your compiler version, and do some tests.

Student
  • 805
  • 1
  • 8
  • 11
pablo1977
  • 4,281
  • 1
  • 15
  • 41
  • Thank you! This is closer to what I was looking for. I did notice you used the standard for C99. I know that C89 could give two different answers because the answer of a negative division problem will round either up or down, which will alter the value given by that formula -- hence resulting in two possible values. So, let me ask... Say you're computing this longhand, like I have been, and you have -4%3. In m - (m/d) * d, does m = -4? – SilvariaKiralv Sep 14 '13 at 15:29
  • I don't understand your lats expression. In standard C (since 1999) you can always trust in this two rules: (1) integer division rounds to 0, and the equality `m % d == m - (m/d)*d` is always true. This implies that `(-4)/3 == -1` (by rule (1)) and, by rule (2): `(-4)%3 == (-4) - ((-4)/3)*3 == (-4) - (-1)*3 == (-4) - (-3) == -4+3 == -1`. In this way, you have also that: `(-4) %% 3 == - (4%3)`. Or well, you also can say that `abs(-4%3) == abs(-4)%3`. – pablo1977 Sep 14 '13 at 16:47
  • 1
    If you are asking about operator precedence, then yes, -4%3 is the same as (-4) % 3, so m%n means that m == -4 here. – pablo1977 Sep 14 '13 at 16:53
1

Like Barmar's linked answer says modulus in a mathematical sense means that numbers are the same class for a ring (my algebra theory is a bit rusty so sorry the terms might be a bit loosely used:)).

So modulus 5 means that you have a ring of size 5. i.e. 0,1,2,3,4 when you add 1 to 4 you are back at zero. so -9,-4,1,6,11,16 are all the same modulo 5 because they are all equivalent. This is actually very important for various algebra theorems but for normal programmers it's pretty much useless.

Basically the standards were unspecified so the modulus returned for negative numbers just has to be one of those equivalent classes of numbers. It's not a remainder. Your best bet in situations like this is to operate on absolute values when doing modulo operators if you want basic integer division. If you are using more advanced techniques (like public key encryption) you'll probably need to brush up on your math a little more.

For now I'd say still with positive ints in this case and have fun programming something interesting.

Jason Tholstrup
  • 2,036
  • 3
  • 21
  • 25
  • "For normal programmers, its pretty much useless" ??? I must be abnormal, as I could not live without it. I'll bet that is true for many others too. Just because you never have a reason to use something, don't speak for the rest. –  Sep 14 '13 at 13:02
  • Definitely going to do my best to stay away from using negatives with mod/remainder whenever I find myself using it. I appreciate your answer! :) – SilvariaKiralv Sep 14 '13 at 15:16
  • @woodchips: In what circumstances is (-7 / 3 == -2, -7 % 3 == -1) more useful than would be (-7 / 3 == -3, -7 % 3 == 2)? I know that's how FORTRAN and many processors' signed-divide instructions behave, but I'm curious how often that's useful. I've encountered many cases where I had to add special code for negative numbers purely because of such rules, and I can't think of any cases where I would have had to write such code given the latter definition but the former definition would have saved me from doing so. – supercat Sep 16 '13 at 22:06