views:

61

answers:

3

I have the following code:

NSInteger index1 = (stop.timeIndex - 1);  //This will be -1
index1 = index1 % [stop.schedule count];  // [stop.schedule count] = 33

So I have the expression -1 % 33. This should give me 32, but is instead giving me 3... I've double checked the values in the debugger. Does anyone have any ideas?

+6  A: 

In C, the modulus operator doesn't work with negative numbers. (It gives a remainder, rather than doing modular arithmetic as its common name suggests.)

mipadi
+1  A: 

The results of using the mod operator on negative numbers are often unexpected. For example, this:

#include <stdio.h>

int main() {
    int n = -1 %  33;
    printf( "%d\n", n );
}

produces -1 with GCC, but I can't see why you expect the expression to evaluate to 32 - so it goes. It's normally better not to perform such operations, particularly if you want your code to be portable.

anon
I'm compiling using LLVM so that probably explains the difference, but 32 is a correct mathematical solution; it's also how python evaluates the expression.
kodai
+1  A: 

C99 says in Section 6.5.5 Multiplicative operators (bold mine):

The result of the / operator is the quotient from the division of the first operand by the second; the result of the % operator is the remainder. In both operations, if the value of the second operand is zero, the behavior is undefined.

When integers are divided, the result of the / operator is the algebraic quotient with any fractional part discarded. If the quotient a/b is representable, the expression (a/b)*b + a%b shall equal a.

It says that % is the remainder, and does not use the word "modulus" to describe it. In fact, the word "modulus" only occurs in three places in my copy of C99, and those all relate to the library and not to any operator.

It does not say anything that requires that the remainder be positive. If a positive remainder is required, then rewriting a%b as (a%b + b) % b will work for either sign of a and b and give a positive answer at the expense of an extra addition and division. It may be cheaper to compute it as m=a%b; if (m<0) m+=b; depending on whether missed branches or extra divisions are cheaper in your target architecture.

Edit: I know nothing about Objective-C. Your original question was tagged C and all answers to date reflect the C language, although your example appears to be Objective-C code. I'm assuming that knowing what is true about C is helpful.

RBerteig