Perl
print 2 % -18;
-->
-16
Tcl
puts [expr {2 % -18}]
-->
-16
but VBScript
wscript.echo 2 mod -18
-->
2
Why the difference?
Perl
print 2 % -18;
-->
-16
Tcl
puts [expr {2 % -18}]
-->
-16
but VBScript
wscript.echo 2 mod -18
-->
2
Why the difference?
Wikipedia's "Modulo operation" page explains it quite well. I won't try to do any better here, as I'm likely to make a subtle but important mistake.
The rub of it is that you can define "remainder" or "modulus" in different ways, and different languages have chosen different options to implement.
The wikipedia answer is fairly helpful here.
A short summary is that any integer can be defined as
a = qn + r
where all of these letters are integers, and
0 <= |r| < |n|.
Almost every programming language will require that (a/n) * n + (a%n) = a. So the definition of modulus will nearly always depend on the definition of integer division. There are two choices for integer division by negative numbers 2/-18 = 0 or 2/-18 = -1. Depending on which one is true for your language will usually change the % operator.
This is because 2 = (-1) * -18 + (-16) and 2 = 0 * -18 + 2.
For Perl the situation is complicated. The manual page says: "Note that when use integer is in scope, "%" gives you direct access to the modulus operator as implemented by your C compiler. This operator is not as well defined for negative operands, but it will execute faster. " So it can choose either option for Perl (like C) if use integer is in scope. If use integer is not in scope, the manual says " If $b is negative, then $a % $b is $a minus the smallest multiple of $b that is not less than $a (i.e. the result will be less than or equal to zero). "
After dividing a number and a divisor, one of which is negative, you have at least two ways to separate them into a quotient and a remainder, such that quotient * divisor + remainder = number: you can either round the quotient towards negative infinity, or towards zero.
Many languages just choose one.
I can't resist pointing out that Common Lisp offers both.
python, of course, explicitly informs you
>>> divmod(2,-18)
(-1, -16)