Split a 4 digit int into 4 variables

I guess this is more of a math question than a programming one.

I have a 4 digit 7seg display that I have to multiplex by the digit with a 959 shift register. So If I want to display the the number 9000 for example I need a function that will take in an int value (0-9999) and store the corresponding 0-9 digit to 4 byte variables (ie ones = 0, tens = 0, hundreds = 0, thousands = 9). I have a bit of code that should logically do just that but it’s not working and I’m getting some very odd results. If I pass in 9000 I get 9020 on the display. For most values it does work.

This is the code that does the calculations I’m pretty sure the error is in here. Kinda tricky to follow and commentate so a million thanks to anyone who can offer advice.

byte ones = 0, tens = 0, hundreds = 0, thousands = 0;

void split(int input_number){
thousands = int(input_number/1000); 

hundreds = int(input_number/100);
hundreds = hundreds-(int(hundreds/10)*10);

tens = int(input_number/10);
tens = tens-(int(tens/10)*10);

ones = input_number-(int(input_number/10)*10);
}

Here is the whole thing ready to compile, and with a little debugging Serial added in.

const int latch = 8; // pin numbers on the board
const int clock = 12;
const int data = 11;
const int digit1 = 2; //thousands
const int digit2 = 3; //hundreds
const int digit3 = 4; //tens
const int digit4 = 5; //ones

int number=9000, 
    time = 50, // how fast the time counts (~4ms increments)
    x = 1;
    
byte ones = 0, tens = 0, hundreds = 0, thousands = 0;

void setup(){
  pinMode(latch, OUTPUT);//Latch
  pinMode(clock, OUTPUT);//Clock
  pinMode(data, OUTPUT);//Data
  pinMode(digit1, OUTPUT);
  pinMode(digit2, OUTPUT);
  pinMode(digit3, OUTPUT);
  pinMode(digit4, OUTPUT);
  digitalWrite(latch, LOW);
  digitalWrite(digit1, LOW);
  digitalWrite(digit2, LOW);
  digitalWrite(digit3, LOW);
  digitalWrite(digit4, LOW);
  
  Serial.begin(9600);
  
}


void loop(){

  split(number);
  writeNumber();
   
  if (number>=9999) x= -1;
  if (number<=0) x= 1;
  number = number + x;
}


void split(int input_number){  // splits and writes the 4 didgit number to the
                               // ones, tens, hundreds, and thousands variables
thousands = int(input_number/1000);

Serial.print(thousands);
Serial.print("   ");


hundreds = int(input_number/100);

Serial.print(hundreds);
Serial.print("   ");

hundreds = hundreds-(int(hundreds/10)*10);

Serial.print(hundreds);
Serial.print("   ");

tens = int(input_number/10);

Serial.print(tens);
Serial.print("   ");

tens = tens-(int(tens/10)*10);
Serial.print(tens);
Serial.print("   ");

ones = input_number-(int(input_number/10)*10);
Serial.print(ones);
Serial.println("   ");

}

byte shiftNumber(byte value) { // converts 0-9 to the correstponding byte for register
  switch (value) {
  case 0: return 1;
  case 1: return 79;
  case 2: return 18;
  case 3: return 6;
  case 4: return 76;
  case 5: return 36;
  case 6: return 32;
  case 7: return 15;
  case 8: return 0;
  case 9: return 12;
  }
}

void writeNumber() {
  
  thousands = shiftNumber(thousands);
  hundreds = shiftNumber(hundreds);
  tens = shiftNumber(tens);
  ones = shiftNumber(ones);

  for (int z=0; z<=time; z++) {
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, thousands); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit1, HIGH); // flash the digit in the correct place
    delay (1);
    digitalWrite(digit1, LOW); 
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, hundreds); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit2, HIGH); // flash the digit in the correct place
    delay (1);
    digitalWrite(digit2, LOW); 
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, tens); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit3, HIGH); // flash the digit in the correct place
    delay (1);
    digitalWrite(digit3, LOW); 
    
    digitalWrite(latch, LOW);
    shiftOut(data, clock, MSBFIRST, ones); // shift in the digit
    digitalWrite(latch, HIGH);
    digitalWrite(digit4, HIGH); // flash the digit in the correct place
    delay (1);
    digitalWrite(digit4, LOW); 
    
    }
}

Thanks!

-Tony

hundreds = hundreds-(int(hundreds/10)*10);

Soo.. hundreds = hundreds - hundreds = 0?

Quit with the int(...) stuff, it's unnecessary and obfuscates the code. hundreds is an int, 10 is an int, so the output is an int. No need to cast it.

I think you may want to check out the modulo operator (%)

Say the number is 1234.

that number divided by 100 is 12.34 which is not an int, then the int casts that to 12. then we take 12 - ((12 / 10 ) [which is 1.2, so cast it to an int again and get just 1] * 10 [now its 10]) [12 - 10 is 2, which is want we want for the hundreds place.

IDK seems to work most of the time...

that number divided by 100 is 12.34 which is not an int

No. An int divided by an int is an int. We're talking computers, here, not math papers.

1234/100 = 12, which IS an int. No need to cast it.

Now, 1234.0/100 is 12.34 and 1234/100.0 is 12.34. But, 1234/100 is 12.

^^^oh gotcha. Okay.

That modulo operator looks interesting, I'm trying to utilize it to get this to work. Thanks

Okay I got it now guys, sorry if this was a trivial question. Thanks for your help!!

ones = (input_number%10);
tens = ((input_number/10)%10);
hundreds = ((input_number/100)%10);
thousands = (input_number/1000);