Iterating Backward using Unsigned Numbers

Warning! Some information on this page is older than 6 years now. I keep it for reference, but it probably doesn't reflect my current knowledge and beliefs.

Thu
01
Mar 2012

I've had a discussion recently with my colleagues about what is the best way of writing a loop in C++ that would iterate backward: Count-1, Count-2, ..., 0, using unsigned integer numbers. I'd like to share all possible solutions I managed to gather.

Iterating forward is simple:

unsigned count = 10;
// Forward: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
for(unsigned i = 0; i < count; ++i)
    printf("%d ", i);

Iterating backward is equally simple and looks similar, if you use signed integers:

// Backward: 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
// Using signed integer
for(int i = count - 1; i >= 0; --i)
    printf("%d ", i);

Same code cannot be used with unsigned integers, because it creates infinite loop, as unsigned number is always >= 0 and just wraps around to maximum value 0xFFFFFFFF:

// WRONG: Inifinte loop, unsigned int wraps around and is always >= 0.
for(unsigned i = count - 1; i >= 0; --i)
    printf("%d ", i);

Changing condition to i > 0 is also invalid, because then loop is not executed for i == 0:

// WRONG: Not executed for i == 0.
for(unsigned i = count - 1; i > 0; --i)
    printf("%d ", i);

Here comes a bunch of possible valid solutions. My favourite is following for loop:

for(unsigned i = count; i--; )
    printf("%d ", i);

Following while loop does same thing. Some people say that it looks more clear. I don't think so, while I believe the for loop is better because it creates local scope for variable i, while the following code does not:

unsigned i = count;
while(i--)
    printf("%d ", i);

Another way of implementing exactly same logic is to write the condition like this. It may look like C++ had the "goes to zero" arrow operator -->, but it is actually just (i-- > 0) :)

unsigned i = count;
while(i --> 0)
    printf("%d ", i);

Another possible solution of loop condition (a one that does not use the postdecrementation operator) is to compare i with maximum integer value. One disadvantage of it is that you have to carefully match the value of the max constant with type of your iterator - whether it is unsigned int, unsigned short etc.

for(unsigned i = count - 1; i != UINT_MAX; --i)
    printf("%d ", i);

Another way of doing this, without using maximum value, is:

for(unsigned i = count - 1; i < count; --i)
    printf("%d ", i);

Finally there are solutions possible that introduce second iterator:

// Option 1 using second iterator:
// i goes 0...9, j is inverted i.
for(unsigned i = 0; i < count; ++i)
{
    unsigned j = count - i - 1;
    printf("%d ", j);
}

// Option 2 using second iterator:
// i goes 10...1, j is decramented i.
for(unsigned i = count; i > 0; --i)
{
    unsigned j = i - 1;
    printf("%d ", j);
}

Which is your favorite loop? Please leave a comment :)

Comments | #algorithms #c++ Share

Comments

[Download] [Dropbox] [pub] [Mirror] [Privacy policy]
Copyright © 2004-2024