Iterating backwards to zero with a byte (or other unsigned number)

This is a simple for loop that's supposed to provide an index number currDigit which should go 3, 2, 1, 0.

for(byte currDigit=3; currDigit>=0; currDigit--) {
  //do stuff
}

However, when currDigit is declared as a byte, the loop goes 3, 2, 1, 0, -1, -2,... until something breaks.

I realized subtracting one from a byte that equals zero (or any other unsigned number) makes the value overflow:
(byte)0 - 1 = B11111111, which is still greater than zero. So the for loop continues forever.

It doesn't really matter if currDigit is a byte or an int in my program, so it's not a big problem for me now.

But, for education's sake: what if currDigit HAD to be a byte or other unsigned number that counted down to zero? What would be a good conditional statement to have in the for loop?

Thanks!

You could always count up and do a subtraction.

eg.

for(byte currDigit = 0; currDigit < 4; currDigit++) {

  byte foo = 3 - currDigit;  // turn into 3, 2, 1, 0

  //do stuff with foo

}

Or exploit the fact that the value rolls over to 255

for (byte currDigit = 3; currDigit != 255; currDigit--) 
{
  //do stuff
}

Yes, but very specific to using the "byte" type. :frowning:

[MarketingSpeak]
"Appropriate test values are available for other unsigned variable types"
[/MarketingSpeak]

For a fee, I presume? :stuck_out_tongue:

In order to fully leverage the advantages of the solution suggested I would advise that you engage our team of experienced consultants who will, no doubt, conclude that you need more consultancy.

In other words, yes :wink:

How about this then?

  const byte limit = 0 - 1;
  for (byte currDigit = 3; currDigit != limit; currDigit--) 
  {
   // do stuff
  }

What about

for(byte n=4; n >0 ; n --) {
  byte currDigit = n - 1
  //do stuff
}

Interesting problem.

...R

void setup( void )
{
  byte currDigit = 3 + 1;
  
  do
  {
    --currDigit;
    // do stuff;
  }
  while ( currDigit != 0 );
}

void loop( void )
{
}

The same structure allows all 256 values to be traversed using a byte variable.

I still think UKHeliBob's solution has merits. :wink:

(The one involving the team of consultants)

Because then, you don't have to think for yourself. :stuck_out_tongue:

 for (byte currDigit = 4; currDigit--;)
{
  //do whatever
}

Having worked for a few very large corporations that occasionally hire "consultants" I wholeheartedly agree.

Because then, you don't have to think for yourself. :stuck_out_tongue:

There is the added benefit that, when something goes horrible wrong, the consultants can be blamed.

The risk is that "consultants are evaluating the situation" is sometimes followed by "we are heeding the consultants' advice and conducting a round of layoffs".

A few other analogies spring to mind right now, but I think I better keep them to myself.

Just to completely change the subject, has anyone visited http://arduino.org/ ?

ainbritain:
But, for education's sake: what if currDigit HAD to be a byte or other unsigned number that counted down to zero? What would be a good conditional statement to have in the for loop?

You could use 'short' which is the same size as a 'byte' but handles short numbers up to a range of 127 in the positive range:

  // for processing "short" numbers up to the range of 127:
  for(short currDigit=3; currDigit>=0; currDigit--) 
  {
    //do stuff
  }

And if it actually has to be a byte, you can do the processig until it rolls over.
If you substract 1 from a byte that is 0, the byte becomes 255.

  // for processing "byte" numbers up to the range of 254:
  for(byte currDigit=3; currDigit<=3; currDigit--) 
  {
    //do stuff
  }

And last but not least: You can tell the C-preprocessor, that a 'byte' shall not be a 'byte' but an 'int' when you are writing your loop:

  #undef byte
  #define byte int
  for(byte currDigit=3; currDigit>=0; currDigit--) 
  {
    //do stuff
  }
  #undef byte
  #define byte unsigned char

As 'byte' is not an internal data type of the C language or the compiler, but it is only defined in the Arduino core files. You can define a 'byte' to be anything you want. Also an int.

jurs:
You could use 'short'...

Right idea. Wrong datatype. int8_t is the correct choice. Or signed char.

yaafm:

 for (byte currDigit = 4; currDigit--;)

Nice. Unfortunately I will never be able to use it. I have a crippling superstition about the post operators.

Huh. Odd.

Is "short" on the arduino only one byte ? I think it is actually the same as an int.

No. Yes. See reply #16.