Thursday, September 09, 2010

Modulus Operator on negative numbers in C

I had been introduced to the C language in the very first day of my B.Sc. course back in 2003. Since then I have been using it for doing quite some varied kinds of programming jobs. But even after so many years, its every now and then that I find out something I did not know before. Here is one such thing that I encountered few days back.

I was taught by both my C teachers in B.Sc. as well as in B.Tech. that the modulus operator in C (denoted by the “%” sign) behaves exactly similar to the mod function that is defined in Mathematics. However here is something weird that I saw recently. Better to show it by code:

   1: #include <stdio.h>
   2:  
   3: #define PRINT_int(x) printf(#x " = %d\n",x)
   4:  
   5: int main() {
   6:  
   7:     PRINT_int( ( 1)%( 6) );    
   8:     PRINT_int( (-1)%( 6) );
   9:     PRINT_int( ( 1)%(-6) );
  10:     PRINT_int( (-1)%(-6) );
  11:  
  12:     return 0;
  13: }

The output given is:


( 1)%( 6) = 1
(-1)%( 6) = -1
( 1)%(-6) = 1
(-1)%(-6) = -1

This does not match at all with the definition of the modulus operation that we have learnt in Mathematics classes. Specifically, modulus can never be negative. So something must be wrong. As it turns out C’s modulo operator behaves differently from the mathematically defined ones when we apply it for negative numbers.

The C90 standard does not define the result of modulus applied on negative numbers, so the result is compiler dependant. But C99 clearly says that the sign of the result is the same is that of the dividend, so in essence for something like:

c = a%b;

The actual operation done is:

c = sign(a) * ( abs(a) % abs(b) );

Where:

  • sign(a)=1 for a>=0
  • sign(a)=-1 for a<0

I figured the rule by myself and later clarified it from the Wikipedia page on Modulo Operation and also from the comp.lang.c group’s "Division and Modulus of Negative Integers” topic.

2 comments:

  1. -1%6 should not be -1 but it should be 5 as per the definition of modulus.check this link
    http://mathforum.org/library/drmath/view/52343.html

    ReplyDelete
  2. @raghuramkalyanam: You are right about the definition of modulus operator in general. However this is about the interpretation of modulus operator as implemented in C language.

    ReplyDelete

I'd love to hear from you !