Identifying individual numerals in an integer - gotta be a better way

Hi,

I have a 4 digit LED display, I can individually set each digit to an ascii character, but what I want to do is write a function to simply write a 4 digit integer straight to the display.

This is what I’ve come up with…

void FourDigitLed::writeInt(int val)
{
  int tho = val/1000;
  int hun = (val-(tho*1000)) /100;
  int ten = (val-(tho*1000)-(hun*100) ) / 10;
  int uni = val - (tho*1000)-(hun*100) - (ten*10);

  //Serial.print("Val = <");Serial.print(val);Serial.print("> OR ...<");Serial.print(tho);Serial.print(hun);Serial.print(ten);Serial.print(uni);Serial.println(">");

  _alpha4.writeDigitAscii(0, (char)(tho+48));  // Thousands
  _alpha4.writeDigitAscii(1, (char)(hun+48));  // Hundreds
  _alpha4.writeDigitAscii(2, (char)(ten+48));  // Tens
  _alpha4.writeDigitAscii(3, (char)(uni+48));  // Units
    
  _alpha4.writeDisplay();
}

The good news is that it seems to work fine, but I can’t help feeling that this is using a hammer to crack an egg, there’s got to be a simpler one-line solution isn’t there?

Yes, the division and modulo operators are very expensive on the Arduino. If you have to run this in a fast loop, like controlling a motor, then the time spent just dividing by 1000 becomes significant.

The correct 'library' solution is to use the itoa() function that's part of the standard C libraries. Unfortunately the Arduino reference doesn't give you any good launchpad to get into that documentation, despite it all being included in the GCC distribution. The best online reference is here: <cstdlib> (stdlib.h) - C++ Reference

Often I just end up rolling my own solution, since I want to output the characters individually. A series of subtractions is faster than division:

void FourDigitLed::writeInt(int val) 
{
  //note val must be positive and less than 9999
  //put some checks in here and show different outputs for those errors
  const int ZERO = 48;  
  char digit;
  for(digit = ZERO; val > 1000; digit++) {
    val-=1000;
  }
  _alpha4.writeDigitAscii(0, digit);  // Thousands

  for(digit = ZERO; val > 100; digit++) {
    val-=100;
  }
  _alpha4.writeDigitAscii(1, digit);  // hundreds

  for(digit = ZERO; val > 10; digit++) {
    val-=10;
  }
  _alpha4.writeDigitAscii(2, digit);  // tens

  for(digit = ZERO; val > 1; digit++) {
    val-=1;
  }
  _alpha4.writeDigitAscii(3, digit);  // units

    
  _alpha4.writeDisplay();
}[/code

Would itoa() really work if you need it to be zero-padded?

For ease of extraction base-10 digits, I tend to use binary-coded decimal a lot.
What is binary-coded decimal? Jones on BCD Arithmetic