Can't Mod Zero?

C++ModuloDivide by-Zero

C++ Problem Overview


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

C++ Solutions


Solution 1 - C++

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 - C++

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 - C++

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 - C++

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 - C++

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.

Solution 6 - C++

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.

Solution 7 - C++

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

Solution 8 - C++

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.

Solution 9 - C++

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDasaruView Question on Stackoverflow
Solution 1 - C++NawazView Answer on Stackoverflow
Solution 2 - C++Mateen UlhaqView Answer on Stackoverflow
Solution 3 - C++Petar IvanovView Answer on Stackoverflow
Solution 4 - C++Billy MoonView Answer on Stackoverflow
Solution 5 - C++MacView Answer on Stackoverflow
Solution 6 - C++K-balloView Answer on Stackoverflow
Solution 7 - C++olljView Answer on Stackoverflow
Solution 8 - C++Anubhav MishraView Answer on Stackoverflow
Solution 9 - C++AnonymousView Answer on Stackoverflow