First, I'll repeat that a modulo b should be equal to a - b * (a div b), and if a language doesn't provide that, you are in an awful mathematical mess. That expression a - b * (a div b) is actually how many implementations calculate a modulo b.
There are some possible rationales. The first is that you want maximum speed, so a div b is defined as whatever the processor used will provide. If your processor has a "div" instruction then a div b is whatever that div instruction does (as long as it is something not totally insane).
The second is that you want some specific mathematical behaviour. Let's first assume b > 0. It is quite reasonable that you want the result of a div b to be rounded towards zero. So 4 div 5 = 0, 9 div 5 = 1, -4 div 5 = -0 = 0, -9 div 5 = -1. This gives you (-a) div b = - (a div b) and (-a) modulo b = - (a modulo b).
This is quite reasonable but not perfect; for example (a + b) div b = (a div b) + 1 doesn't hold, say if a = -1. With a fixed b > 0, there are usually (b) possible values for a such that a div b gives the same result, except there are 2b - 1 values a from -b+1 to b-1 where a div b equals 0. It also means that a modulo b will be negative if a is negative. We'd want a modulo b to be always a number in the range from 0 to b-1.
On the other hand, it is also quite reasonable to request that as you go through successive values of a, a modulo b should go through the values from 0 to b-1 then start with 0 again. And to request that (a + b) div b should be (a div b) + 1. To achieve that, you want the result of a div b to be rounded towards -infinity, so -1 div b = -1. Again, there are disadvantages. (-a) div b = -(a div b) doesn't hold. Repeatedly dividing by two or by any number b > 1 will not eventually give you a result of 0.
Since there are conflicts, languages will have to decide which set of advantages is more important to them and decide accordingly.
For negative b, most people can't get their head around what a div b and a modulo b should be in the first place, so a simple way is to define that a div b = (-a) div (-b) and a modulo b = (-a) modulo (-b) if b < 0, or whatever is the natural outcome of using the code for positive b.
(-3)/2 == -1
. This definition can be useful. When you want%
to be consistent with this division fulfillingx == (x/y)*y + x % y
you end up with the definition of%
used in C#.