23

Perl

print 2 % -18;

-->

-16

Tcl

puts [expr {2 % -18}]

-->

-16

but VBScript

wscript.echo 2 mod -18

-->

2

Why the difference?

bugmagnet
  • 7,233
  • 7
  • 57
  • 121
  • Thanks for sharing this. I've tested in Python, Ruby, Javascript and bash now. JS and bash both said 2 and the other said -16. – PEZ Jan 16 '09 at 13:55
  • Modulo operations mainly belong to Counting numbers and are arbitrarily defined outside of that. – Axeman Jan 16 '09 at 14:46

4 Answers4

31

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

Nick Fortescue
  • 40,193
  • 23
  • 99
  • 131
  • Re "can do anything", no. If use integer is in scope it can only do what C does, and the C standard explicitly requires (a/n) + (a%n) = a but allows either choice for integer division. – ysth Jan 19 '09 at 11:26
  • (100/2)+(100%2) != 100 ... am I missing something? – B T Apr 20 '10 at 21:03
  • @B T, oops, missed out a factor of n, thanks for spot, I'll fix it – Nick Fortescue Apr 30 '10 at 15:40
9

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.

Jon Skeet
  • 1,261,211
  • 792
  • 8,724
  • 8,929
  • I think your original answer struck right at the heart it. Sometimes '%' means "remainder" and sometimes it means "modulus", which aren't the same thing. – Bill the Lizard Jan 16 '09 at 13:56
  • @Bill: I wasn't sure about deleting it, but then it comes down to the definition of "remainder" and "modulus" which are *also* (apparently) not as clear cut as one would like. – Jon Skeet Jan 16 '09 at 14:53
4

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.

Svante
  • 46,788
  • 11
  • 77
  • 118
3

python, of course, explicitly informs you

>>> divmod(2,-18)
(-1, -16)
popcnt
  • 4,009
  • 1
  • 14
  • 14