Can't Mod Zero?

64,719

Solution 1

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.

Solution 2

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

Solution 3

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)

Solution 4

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

Solution 5

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.

Share:
64,719
Dasaru
Author by

Dasaru

Updated on March 22, 2021

Comments

  • Dasaru
    Dasaru about 3 years

    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)?

  • mu is too short
    mu is too short over 12 years
    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
    mu is too short over 12 years
    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.
  • hammar
    hammar over 12 years
    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.
  • K-ballo
    K-ballo over 12 years
    True you, the quirks of mod. But alas it is enough to illustrate why one cannot mod by zero.
  • Nawaz
    Nawaz over 12 years
    @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
  • mu is too short
    mu is too short over 12 years
    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.
  • Zaffy
    Zaffy over 11 years
    Is it possible to crash program using mod zero or just result is unknown ?
  • Nawaz
    Nawaz over 11 years
    @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.
  • phuclv
    phuclv over 10 years
    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 stackoverflow.com/questions/1907565/…
  • Yatharth Agarwal
    Yatharth Agarwal over 10 years
    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?
  • mafso
    mafso over 9 years
    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
    mafso over 9 years
    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.
  • Masood Lapeh
    Masood Lapeh about 5 years
    My program crashed silently without any error message, and that was the problem.
  • Dominick Pastore
    Dominick Pastore over 3 years
    @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.
  • Nikita Demodov
    Nikita Demodov almost 3 years
    mod can only be used on integers -- so why are you talking about floats?
  • Anonymous
    Anonymous almost 3 years
    @NikitaDemodov Where did I talk about floats?
  • Nikita Demodov
    Nikita Demodov almost 3 years
    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.
  • Anonymous
    Anonymous almost 3 years
    @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.