[Solved] Fixing Function to Decrement Place Value Variables

I am programming a simple counter, to increment and decrement with the push of respective buttons.

Why does ++ work with byte type variables, at least it seemed to work...?

Why does -- not work?

The documentation doesn't seem confident it works for unsigned data types.

I'd like to know what's going on under the hood so I can better understand the behavior of the bug...

-- works fine for both byte and char. Show us your evidence that it doesn't.

Are you going to supply any proof it does not work?

Paul

Delta_G: -- works fine for both byte and char. Show us your evidence that it doesn't.

Paul_KD7HB: Are you going to supply any proof it does not work?

Paul

Sorry my decrement function isn't working as expected, and I thought this was the problem... Clearly, it isn't. Here are both functions, for incrementing, and decrementing. The place values are separated to facilitate multiplexing an LED matrix.

void incrementCount() {
  if (unitCountOnes >= 9) {
    unitCountOnes = 0;
    if (unitCountTens >= 9) {
      unitCountTens = 0;
      if (unitCountHundreds >= 9) {
        unitCountHundreds = 0;
        if (unitCountThousands >= 9) {
          unitCountThousands = 0;
        }
        else unitCountThousands++;
      }
      else unitCountHundreds++;
    }
    else unitCountTens++;
  }
  else unitCountOnes++;
}

void decrementCount() {
  if (unitCountOnes = 0) {
    unitCountOnes = 9;
    if (unitCountTens = 0) {
      unitCountTens = 9;
      if (unitCountHundreds = 0) {
        unitCountHundreds = 9;
        if (unitCountThousands = 0) {
          unitCountThousands = 9;
        }
        else unitCountThousands--;
      }
      else unitCountHundreds--;
    }
    else unitCountTens--;
  }
  else unitCountOnes--;
}

If there's a problem with that code, I don't see it.

Suspect problem is elsewhere, in the code you haven't posted.

void decrementCount() {
  if (unitCountOnes = 0) {

    if (unitCountTens = 0) {

      if (unitCountHundreds = 0) {

        if (unitCountThousands = 0) {

Ooops...

DrAzzy: If there's a problem with that code, I don't see it.

Suspect problem is elsewhere, in the code you haven't posted.

== vs = It took me a LONG while to see it too.

and what is the purpose of this code? computers can do numbers bigger then 9

I usually use something like:

// to count up
unitCountOnes++;
doCarries();


// to count down
unitCountThousands += 9;
unitCountHundreds += 9;
unitCountTens += 9;
UnitCountOnes += 9;
doCarries();


// to do the carries when counting in either direction
void doCarries() {
  if (unitCountOnes >= 10) {
    unitCountOnes -= 10;
    unitCountTens++;
  }
  if (unitCountTens >= 10) {
    unitCountTens -= 10;
    unitCountHundreds++;
  }
  if (unitCountHundreds >= 10) {
    unitCountHundreds -= 10;
    unitCountThousands++;
  }
  if (unitCountThousands >= 10) {
    unitCountThousands -= 10;
    // our counter has no higher digit to which to carry
  }
}

I can't imagine what for are the unitCounts?

Juraj: I can't imagine what for are the unitCounts?

If you use 8-bit shift registers to multiplex 8 7-segment LEDs, you need a single value for each digit.

Wow.

How did I miss that.

Perehama: If you use 8-bit shift registers to multiplex 8 7-segment LEDs, you need a single value for each digit.

I would count the usual way and take apart the number for display

Juraj: I would count the usual way and take apart the number for display

If you could show me this in code, I would appreciate it. My own attempts to generate such code have resulted in division which consumes enough mcu processes to have a noticeable affect on the display refresh.

displaying is in interrupt? the countdown is in milliseconds? at least I would use array for the units

Juraj: displaying is in interrupt? the countdown is in milliseconds? at least I would use array for the units

It is not necessary to be so precise as an interrupt, I use non-blocking code and micros() timekeeping for the display refresh, which can vary a little as long as the human eye perceives the display is lit as a whole. The count is not time, but cardinal units. An array ends up less readable in code.

Simpler using array of digits, recursive carry function:

byte count_digit[4] ;

void increment (byte index = 0)
{
  if (index >= 4) // overflow top digit
    return ;
  if (count_digit[index] == 9)
  {
    count_digit[index] = 0;
    increment (index+1) ;
  }
  else
    count_digit[index] ++ ;
}

// then to increment by one, call "increment()"

For fastest decode of int to decimal digits divide and conquer:

void decode_digits (unsigned int value)
{
  high_part = value / 100 ;
  low_part = value - 100 * high_part ;  // split into two small problems

  thousands = high_part / 10 ;
  hundreds = high_part - 10 * thousands ;
  tens = low_part / 10 ;
  units = low_part - 10 * tens ;

Note only 3 divisions, no remainders, and multiplies are done in hardware anyway, and the smaller divides can be done with table lookup if required for ultimate performance, leaving a single divide by 100.

You can do also better

void Operation (byte index, char addiction)
{
value [index%4]=(value[index%4]+(2*addiction-1))%9
}

I think it is what you want.
Addiction=0->-1
Addiction=1->+1

Silente: You can do also better

void Operation (byte index, char addiction)
{
value [index%4]=(value[index%4]+(2*addiction-1))%9
}

I think it is what you want. Addiction=0->-1 Addiction=1->+1

Addiction?? Besides, that code can't be right. Why the modulo 9 ?

MarkT: For fastest decode of int to decimal digits divide and conquer:

void decode_digits (unsigned int value)
{
  high_part = value / 100 ;
  low_part = value - 100 * high_part ;  // split into two small problems

  thousands = high_part / 10 ;   hundreds = high_part - 10 * thousands ;   tens = low_part / 10 ;   units = low_part - 10 * tens ;



Note only 3 divisions, no remainders, and multiplies are done in hardware anyway, and the smaller
divides can be done with table lookup if required for ultimate performance, leaving a single divide by 100.

Or, you could get rid of the multiplications and divisions entirely.

int leftover = value_to_be_converted;
byte thou = 0;
byte hund = 0;
byte tens = 0;
byte ones = 0;
while (leftover >= 1000) { leftover -= 1000; thou++; }
while (leftover >=  100) { leftover -=  100; hund++; }
while (leftover >=   10) { leftover -=   10; tens++; }
ones = leftover;