Efficient Modulo decrement

Jun 01, 2007 5 Replies

Hi ,



Feeling a bit stupid asking this but could any one tell me an efficient way to modulo decrement. I know how to modulo increment for powers of two i.e -



if i want to modulo 16 increment a char i would do something like -



#define MODULO_SIZE 16



int modulo_increment(int isequence) { //increment isequence++; //map to current size isequence &= (MODULO_SIZE-1); return(isequence); }



but how do I efficiently modulo decrement



Thanks in advance



rate



I've got a feeling that simple:

isequence++; if (MODULO_SIZE == isequence) { isequence = 0; }

will generate the same (or even better) code with most modern compilers. In other words, the compiler will do such tricks for you.

Well, replacing ++ with --, the same idea will work (at least in cases where MODULO_SIZE is a positive integral power of 2, as the original).

Best regards, Spehro Pefhany

"it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com

It certainly shouldn't generate the same code, because you're asking for something rather different.

Consider the case where you call the function with isequence == MODULO_SIZE. If the ints happen to be 32 bits, it might take quite a few years to get back into sequence.

Best regards, Spehro Pefhany

"it's the network..." "The Journey is the reward" speff@interlog.com Info for manufacturers: http://www.trexon.com Embedded software/hardware/analog Info for designers: http://www.speff.com

:-)

It was not my intention to demonstrate the equivalent code. (But well spot on, anyway). Just the word 'efficient' together with a trick of '& (MODULO_SIZE-1)' caught my eye. And my message was: this particular trick is probably no more efficient than other, more straightforward, implementation. That's all.

isequence++; isequence %= MODULO_SIZE; will work for any MODULO_SIZE, and if it happens to be a power of 2, the compiler will do the AND operation for you. Good week-end to everyone.

Indeed. Note that you need to use an unsigned variable for this to be as efficient as the &, and for non-powers of 2 Sphero's sequence is best. The most generic and yet efficient solution allows both variable increments and maximum:

unsigned i, inc, max; for (i %= max, inc %= max; ... ; (i += inc) >= max ? i - max : i) // loop using i

Note i, inc and max can be changed in the loop as long as i < max and inc < max. To answer the OP's question, set inc = max-1.

Wilco

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required