To answer the actually asked question, i.e. the floating point case.
What happens exactly can be traced down the call chain as already shown. The difference mostly boils down to attention to rounding and cancellation issues.
That depends on how sensitive your code is to getting a result out of range.
I would expect that mod(-7,3) results in -1 but I know that this is implementation specific (or if you want depends on the mathematical definition).
-7 / 3 = -3 remainder 2
So “strange” is bad wording, lets say it may be surprising, depending on what you expect.
In this sense it is not wrong to implement it the way one wants to have it.
I think it is the documented behavior: from ?mod (emphasis is mine),
The reduction of x modulo y, or equivalently, the remainder of x after floored division by y, i.e. x -
y*fld(x,y) if computed without intermediate rounding.
The result will have the same sign as y, and magnitude less than abs(y) (with some exceptions, see note below).
But maybe the wording is a bit indirect — please consider making a small PR to this docstring with the example above.
Note that Julia agrees with C and Python. Java disagrees, and is arguably wrong since it means that fld in Java rounds to 0 instead of -Inf, which is very annoying for some purposes.
whether the documented behavior is correct (it is),
whether it could be explained a bit better (yes, and people stumbling into it are in the best position to do so),
is it violating some common consensus or expectation (like 1 + 3 returning 9).
(3) is much harder to argue here as different languages have apparently different semantics. In any case, it cannot be changed before 2.0 as it would be breaking, and it is unlikely that people would want to break this, but you can always open an issue about it.
mathematical definition of reminder also agrees with mod (not saying math people always have the most convenient definition for programming purpose), just that in no way is this strange
If a and d are integers, with d non-zero, it can be proven that there exist unique integers q and r , such that a = qd + r and 0 ≤ r < |d| . The number q is called the quotient , while r is called the remainder .
I believe you should think of modular arithmetic as something that always wraps around into the same range (0 to something). Here, it is illustrated with a clock: Modular arithmetic - Wikipedia It would be strange to not coerce time to fall into the 12-to-12 (or even better, 0-24) range.
As far as I understand, the difference in sign behaviour is exactly what distinguishes mod from rem.