tags:

views:

2291

answers:

2

Duplicate of Weird Objective-C Mod Behavior

I'm trying to mod an integer to get an array position so that it will loop round. Doing i % arrayLength works fine for positive numbers but for negative numbers it all goes wrong.

so i need an implementation of

int GetArrayIndex(int i, int arrayLength)

such that

GetArrayIndex(-4, 3) == 2
GetArrayIndex(-3, 3) == 0
GetArrayIndex(-2, 3) == 1
GetArrayIndex(-1, 3) == 2
GetArrayIndex( 0, 3) == 0
GetArrayIndex( 1, 3) == 1
GetArrayIndex( 2, 3) == 2
GetArrayIndex( 3, 3) == 0
GetArrayIndex( 4, 3) == 1

I've done this before but for some reason it's melting my brain today :(

+2  A: 

Just add your modulus (arrayLength) to the negative result of % and you'll be fine.

starblue
+22  A: 

I always use my own mod function, defined as

int mod(int x, int m) {
    return (x%m + m)%m;
}

Of course, if you're bothered about having two calls to the modulus operation, you could write it as

int mod(int x, int m) {
    int r = x%m;
    return r<0 ? r+m : r;
}

or variants thereof.

The reason it works is that "x%m" is always in the range [-m+1, m-1]. So if at all it is negative, adding m to it will put it in the positive range without changing its value modulo m.

ShreevatsaR
Note: for complete number-theoretic completeness, you might want to add a line at the top saying "if(m<0) m=-m;" although in this case it doesn't matter as "arrayLength" is presumably always positive.
ShreevatsaR
If you are going to check the value of m, you should also exclude zero.
billpg