66

Why is X % 0 an invalid expression?

I always thought X % 0 should equal X. Since you can't divide by zero, shouldn't the answer naturally be the remainder, X (everything left over)?

Sumurai8
  • 20,333
  • 11
  • 66
  • 100
Dasaru
  • 2,828
  • 5
  • 25
  • 25
  • @xanatos Me too. I gave the other +1 to balance the other -1... I suspect it's highly duplicated, but then it should have been voted to be closed. –  Sep 10 '11 at 07:42
  • @pst: possible duplicate of [Why is this a floating point exception?](http://stackoverflow.com/questions/1081250/why-is-this-a-floating-point-exception) but it wasn't exactly easy to find. – mu is too short Sep 10 '11 at 08:15
  • 1
    @Mu the response are quite different. Here Petar explains how `%` is mathematically defined, there they explain why the error is that instead of something more clear. – xanatos Sep 10 '11 at 09:36
  • 1
    (from a now-deleted link-only answer of Dean Inada) Knuth et al. in [Concreate Mathematics](http://en.wikipedia.org/wiki/Concrete_Mathematics) give the same definition as yours. ([PDF](http://www.csie.ntu.edu.tw/~r97002/temp/Concrete%20Mathematics%202e.pdf), page 82, definition 3.22.) – Csq Aug 25 '14 at 01:09
  • 1
    You can't have a remainder of something that you didn't divide. – JohnJohn Jan 23 '17 at 13:01
  • 2
    Very poor conceptualization and reasoning here. Since the quotient from dividing by 0 is undefined, so must the remainder be. And it's very odd to have "always thought" something that you surely were never taught or told. – Jim Balter Oct 14 '17 at 04:14
  • 1
    "the response are quite different" -- that has nothing to do with whether the questions are duplicates. Sheesh. – Jim Balter Oct 14 '17 at 04:15

9 Answers9

50

The C++ Standard(2003) says in §5.6/4,

[...] If the second operand of / or % is zero the behavior is undefined; [...]

That is, following expressions invoke undefined-behavior(UB):

X / 0; //UB
X % 0; //UB

Note also that -5 % 2 is NOT equal to -(5 % 2) (as Petar seems to suggest in his comment to his answer). It's implementation-defined. The spec says (§5.6/4),

[...] If both operands are nonnegative then the remainder is nonnegative; if not, the sign of the remainder is implementation-defined.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • I'd probably lean towards "*partly* implementation defined", the sign is implementation defined but wouldn't the value be fixed once the sign is chosen? But that's just nit picking. – mu is too short Sep 10 '11 at 07:51
  • 1
    Is it possible to crash program using mod zero or just result is unknown ? – Zaffy Oct 02 '12 at 11:29
  • 1
    @Zaffy: Since mod zero invokes undefined behavior (UB), so yes, it is *possible* to crash your program using mod zero, but it is **not** *guranteed* to crash your program. Program crash is just one out of the million possibilities of UB. – Nawaz Oct 02 '12 at 11:46
  • 1
    This was linked as a duplicate, and I think this post should be made up-to-date: It's no longer implementation-defined, but `a/b + a%b` is `a` for all `a` and `b` where the quotient is defined (the behaviour is undefined otherwise). The change happened in C99 and C++11 (maybe already in C++03 with TR1, don't know). Would be nice, if you could also tag the question as C, as they are the same in this respect (it was a C question which duplicated this). – mafso Aug 16 '14 at 17:33
  • And in case you wonder why C99 and C11 differ (not sure about C++), I remember this to be a defect in C99: `INT_MIN % -1` was defined, although it throws an exception on many platforms. In C11, `x%y` is defined only if `x/y` is, and it was never safe to assume `INT_MIN % -1` to evaluate. – mafso Aug 16 '14 at 17:39
  • My program crashed silently without any error message, and that was the problem. – Masood Lapeh Feb 24 '19 at 14:12
14

This answer is not for the mathematician. This answer attempts to give motivation (at the cost of mathematical precision).

Mathematicians: See here.

Programmers: Remember that division by 0 is undefined. Therefore, mod, which relies on division, is also undefined.


This represents division for positive X and D; it's made up of the integral part and fractional part:

(X / D) =   integer    +  fraction
        = floor(X / D) + (X % D) / D

Rearranging, you get:

(X % D) = D * (X / D) - D * floor(X / D)

Substituting 0 for D:

(X % 0) = 0 * (X / 0) - 0 * floor(X / 0)

Since division by 0 is undefined:

(X % 0) = 0 * undefined - 0 * floor(undefined)
        = undefined - undefined
        = undefined
Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
  • Why can't you just substitute 0 for the outer D in the second equation making it `(X % 0) = 0 * (w/e)` and just call it zero? – Yatharth Agarwal Nov 29 '13 at 05:52
  • @YatharthAgarwal Because `0 * (w/e)` *isn't* always 0. If `w/e` is a real number (which includes integers), then it's 0. If not, regular multiplication doesn't give us an answer, i.e., the answer is undefined. – Dominick Pastore Sep 05 '20 at 16:52
6

X % D is by definition a number 0 <= R < D, such that there exists Q so that

X = D*Q + R

So if D = 0, no such number can exists (because 0 <= R < 0)

Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
  • 2
    That's not true, AFAIK the sign of `x % y` is implementation defined if `x < 0`. `-5 % 2` happens to be -1 on my system. – mu is too short Sep 10 '11 at 07:08
  • `X = D*Q + R` works for _any_ `Q` when `D = 0`, with `X = R` as the OP wanted. It's the `0 <= R < 0` that's impossible to satisfy. Your answer seems to imply that it's the other way round, though I might just be reading it wrong. – hammar Sep 10 '11 at 07:11
  • 2
    @Petar: No. `-5 % 2` is NOT `-(5 % 2)` in fact. It's implementation-defined. The spec says, *If both operands are nonnegative then the remainder is nonnegative; **if not, the sign of the remainder is implementation-defined*** – Nawaz Sep 10 '11 at 07:38
  • 1
    The above is true for mathematics modulus. But CPUs and C compiler implementations often return R that have the same sign as X, so -5 % 2 = -(5 % 2) is true. OTOH Python will return the "true" mathematics modulus so the above wouldn't be true anymore http://stackoverflow.com/questions/1907565/c-python-different-behaviour-of-the-modulo-operation – phuclv Oct 29 '13 at 01:11
2

I think because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.

However, the best solution in line with your thinking would be to do something like this

REMAIN = Y ? X % Y : X
Billy Moon
  • 57,113
  • 24
  • 136
  • 237
2

Another way that might be conceptually easy to understand the issue:

Ignoring for the moment the issue of argument sign, a % b could easily be re-written as a - ((a / b) * b). The expression a / b is undefined if b is zero, so in that case the overall expression must be too.

In the end, modulus is effectively a divisive operation, so if a / b is undefined, it's not unreasonable to expect a % b to be as well.

Mac
  • 14,615
  • 9
  • 62
  • 80
1

X % Y gives a result in the integer [ 0, Y ) range. X % 0 would have to give a result greater or equal to zero, and less than zero.

Anonymous
  • 738
  • 4
  • 14
  • 36
K-ballo
  • 80,396
  • 20
  • 159
  • 169
0

you can evade the "divivion by 0" case of (A%B) for its type float identity mod(a,b) for float(B)=b=0.0 , that is undefined, or defined differently between any 2 implementations, to avoid logic errors (hard crashes) in favor of arithmetic errors...

by computing mod([a*b],[b])==b*(a-floor(a))
INSTREAD OF
computing mod([a],[b])

where [a*b]==your x-axis, over time [b] == the maximum of the seesaw curve (that will never be reached) == the first derivative of the seesaw function

https://www.shadertoy.com/view/MslfW8

king_nak
  • 11,313
  • 33
  • 58
ollj
  • 1
0

I suppose because to get the remainder of X % 0 you need to first calculate X / 0 which yields infinity, and trying to calculate the remainder of infinity is not really possible.

However, the best solution in line with your thinking would be to do something like this,

ans = Y ? X % Y : X

Also, in C++ docs its written that X % 0 or X / 0 ,results in an undefined value.

0

How computers divide:

Start with the dividend and subtract the divisor until the result is less then the divisor. The number of times you subtracted is the result and what you have left is the remainder. For example, to divide 10 and 3:

10 - 3 = 7
7 - 3 = 4
4 - 3 = 1

So

10 / 3 = 3
10 % 3 = 1

To divide 1 and 0:

1 / 0
1 - 0 = 1  
1 - 0 = 1  
1 - 0 = 1  
...

So

1 / 0 = Infinity (technically even infinity is too small, but it's easy to classify it as that)
1 % 0 = NaN

If there is nothing to stop it, the CPU will continue to execute this until it overloads and returns a totally random result. So there is an instruction at the CPU level that if the divisor is 0, return NaN or Infinity (depending on your platform).

This will never end so the remainder is undefined (which is NaN for computers).

Anonymous
  • 738
  • 4
  • 14
  • 36
  • mod can only be used on integers -- so why are you talking about floats? – Nikita Demodov Jun 04 '21 at 21:54
  • @NikitaDemodov Where did I talk about floats? – Anonymous Jun 04 '21 at 23:55
  • when you said `1 / 0 = Infinity` and `1 % 0 = NaN`. Integers have no `inf` and `NaN` values. They are exclusive to floats of the IEEE754 standard. `1.0 / 0.0` is `inf`, but `1 / 0`(if both are integers) is a crash. – Nikita Demodov Jun 05 '21 at 09:45
  • @NikitaDemodov The float equivelents are `Infinity` and `NaN`, if it's an integer it would fail to convert it to the proper type but the concept is the same. – Anonymous Jun 05 '21 at 15:14