Reputation: 5856
Say I have a zero-based range like
[0, 1, 2, 3, 4]
these are essentially the indexes of an array with size = 5. Is it possible to use a signed integer variable to continuously loop up or down in that range?
By up or down, I mean that the variable is permitted to perform arbitrarily many increment or decrement operations:
++index;
--index;
index += offset;
index -= offset;
So for example decrementing the index should map to following values:
index = 2;
while (/*...*/)
{
--index;
index_in_range(index, 5);
}
The function index_in_range(index, 5)
would output:
1, 0, 4, 3, 2, 1, 0, 4, 3, 2, 1, .... and so on
The positive case is just a modulo operation over the range size, but for the negative I can't figure out how the mapping goes.
EDIT :
The requested function index_in_range(int idx, int range)
takes an arbitrary integer, i.e. could be called as index_in_range(-245, 14)
. The example given does use a decrement operator but I never said I'm only offsetting by one each time.
Upvotes: 0
Views: 261
Reputation: 139
To increase
index = (index+1)%size;
To decrease
index = (index-1+size)%size
Upvotes: 1
Reputation: 41513
C made a really poor decision for %
to round towards zero, rather than be a straightforward floor, so the math's clunkier than it has to be. Basically, though, you want (index % size + size) % size
. That code starts by chopping off the negative or positive multiples to bring the index into the range (-size, size)
, adds size
to map it into (0,size*2)
, and a final %
to map it into [0,size)
.
If size
is not known at compile time, it's likely more performant to replace everything after the first modulus with a conditional: index %= size; if(index < 0) index += size;
.
Upvotes: 1