6

Given an array of length size and an index n to that array, how can I wrap the index such that it is always within size-1? For positive numbers its simply n % size, but how to achieve backwards wrap around when n is negative?

What I've come up with:

int wrap(int size, int n) {
    if (n >= 0)
        return n % size;
    else
        return abs(size + n) % size;
}

But this only works for n <= size; How to make it work for any n?

Expected output:

wrap(4, -1) == 3
wrap(4, -2) == 2
wrap(4, -3) == 1
wrap(4, -4) == 0
wrap(4, -5) == 3
wrap(4, -6) == 2
wrap(4, -7) == 1
wrap(5, -8) == 0
Anonymous Entity
  • 3,254
  • 3
  • 27
  • 41

1 Answers1

17

You want the modulo operator with floored division.

int mod_floor(int a, int n) {
    return ((a % n) + n) % n;
}
Joseph Thomson
  • 9,888
  • 1
  • 34
  • 38
  • The first % is superfluous. `(a+n)%n` works fine if a >= -n. – Fabian Mar 03 '20 at 09:53
  • 2
    @Fabian "It's superfluous when `a >= -n`". Who said `a >= -n`? :/ – Joseph Thomson Mar 06 '20 at 11:41
  • Modulo on negative numbers leads to unexpected results. Hence it should Be avoided. Furthermore the first modulo operation has no benefit und should be removed. – Fabian Mar 07 '20 at 16:15
  • 1
    @Fabian In what way does it lead to unexpected results? The result is perfectly well defined. The first modulo operation allows the function to work when `a >= -n`, so it has a benefit and should not be removed. – Joseph Thomson Mar 09 '20 at 11:11
  • 1
    Sorry, you are right! – Fabian Mar 12 '20 at 05:54