For this reason, Zig requires the programmer to specify which is intended when the operator is used on signed integers:
var x: i32 = -17 % 12; //compile error: remainder division with '(integer literal)' and '(integer literal)': signed integers and floats must use @rem or @mod
var y: i32 = @mod(-17, 12); //7
var z: i32 = @rem(-17, 12); //-5
Correct me if I'm wrong, but this is also attractive because it can be applied even to an "actual modulo" operator. That is, because "(x mod n + n) mod n" has the same behavior as the above, one need not even know which way a particular language's "%" operator behaves if one just always uses this filter.
a = b ( mod n) is defined as
n | a - b
That is n is a divisor of a -b
( a, b, n integers n non zero)
Obviously if p is prime and p | n
Then also a = b ( mod p)
I know. But programming languages usually don’t have the modulo relation but a modulo operator that sends each number to a special representative of its equivalence class. For positive numbers, everyone agrees that this should be the smallest nonnegative number (i.e. the representative between 0 and n – 1). However, there are two conventions for the representative of a negative number: Some programming languages return the largest nonpositive number (the article calls this the remainder), others return the smallest nonnegative number in this case as well (the article calls this the modulus). I chose to write mod and rem instead of % to be able to make this distinction.
I recalling seeing these referred to as modp (positive) and mods (symmetric) back in University. This seems to be the clearest way to distinguish them. I didn't realize different popular programming languages used different versions for the % operator...
The case of a negative denominator doesn't seem to make sense when talking about modulo in an algebraic sense. I don't think you can have a Ring with a negative dimension. So I've never even thought about what % would do with a negative denominator (RHS). If I was using % with an unknown denominator as input, I could just as easily end up with it being 0 which would be a bad thing, so I think it's fair to say I always require it to be positive.
No, the symmetric version is yet a third variant. What people are calling “rem” is what you get with division that rounds toward zero, whereas what they are calling “mod” is what you get with division that always rounds down. A symmetric version is what you get with division that rounds to the nearest integer, and I have not seen any language with a built-in operator for it.
To the grandparent:
> sends each number to a special representative of its equivalence class
The problem is that many programming languages have a “remainder” type % operator which does not do this in the case where the dividend is negative. For instance,
-1 % 3 == -1
2 % 3 == 2
Instead, folks who want mathematically reasonable behavior need to implement their own. For instance in Javascript we can define
Grandparent here: I know, that’s what I tried to explain (poorly) with the next sentences. Programming languages with a remainder operator choose two representatives for every equivalence class except [0] and return the one that has the same sign as the dividend.
I tend to define
mod = (a, b) => (a % b + b) % b
because it works without going through floats – in languages that have integer types. I don’t know if there are actual advantages though.
Well, algebraically, Z/nZ and Z/(–n)Z are the same. However, you have again some choice of canonical representative (and you might choose differently for n and –n). But I agree that this is a rather rare case.
I don't think there is a formal universal distinction in programming between a "modulo operator" and a "remainder operator" in terms of behaviour. Wikipedia says that the result of a modulo operation varies between languages [0]. Furthermore, by mathematical convention as seen in the Euclidean division theorem, the remainder is always in [0, n).
However, the real distinction lies in how the two operations handle negative dividends: If n is positive, the modulo operator
always returns a number between 0 and n – 1. The remainder operator returns a number between –n + 1 and 0 if x is negative instead. For example, and I have yet to see a case where the remainder operator is the one that you want. If a language only supports rem I find myself constantly writing (which is just