How to use return x; in for inside function?

Hi,
i wrote function for returning digit from Int, counting from left side.
Then i tried to shorten it into few lines, but i'm stuck at:

If i repeat my code few times everything works correctly. But if put it inside for loop it crashes. I think it's because return only returns me from a for loop, not from the function itself.

long AddZeroToTen(byte howManyTimes) {
  long x = 10;
  for (byte i = 0; i < howManyTimes; i++) {
    x *= 10;
  }
  return x;
}

int returnDigit(int n, byte whichDigit) {
  int d[6];
  byte count = 1;

  for (byte i = 1; i <= 5; i++) {
  d[count] = n;
  while (d[count] >= AddZeroToTen(count - 1) || d[count] <= -AddZeroToTen(count - 1)) d[count] /= 10;
  d[count] -= d[count - 4] * 10000 + d[count - 3] * 1000 + d[count - 2] * 100 + d[count - 1] * 10;
  if (whichDigit == count && (n > AddZeroToTen(count - 2) - 1 || n < -AddZeroToTen(count - 2) - 1)) return d[count];
  count++;
  } // for
  
  return false;
} // function

int number = 1234;


void setup() {
  Serial.begin(9600);

  for (int i = 1; i <= 5; i++) {  Serial.println(returnDigit(number, i)); }

  Serial.println(F("-------------"));
  number = -1234;

  for (int i = 1; i <= 5; i++) {  Serial.println(returnDigit(number, i)); }
}

void loop() {}

What should i do?

Utter nonsense. return returns from the function. break kicks you out of any loop.

Why not put some prints inside the function, so you can SEE what is really happening, rather than just guessing?

Do you not see a problem with this line??

no? It prints from 1 to 5. It mean first position is really 1, not 0 - like all other things there. It was easier during writing it, i know it waste my space cuz i don't use [0] position on any array right now. I'll change it later.

Famous last words :grinning:

I can't follow your logic, but you are writing to d[count], and count starts as 1, so presumably increments to 5, right? You NEVER write d[0], and probably do write d[5], which does not exist, which will scribble on the stack, surely corrupting the value of count.

I can't follow your logic, but you are writing to d[count], and count starts as 1, so presumably increments to 5, right? You NEVER write d[0],

I want to count first value as 1 not 0. I write code around that. In final version i wanted to modify it so to not leave empty d[0], but i didn't wanted to make code harder to read during writing

and probably do write d[5], which does not exist, which will scribble on the stack, surely corrupting the value of count.

Thanks! I think i changed it to 6 but then changed code to earlier version. I didn't check that, sadly there is no compiler error

If u want to read it, i added version of this code before i tried to squeeze it into few lines:

extern int returnDigit(int n, int whichDigit) {

  int d1 = n;
  while (d1 >= 10 || d1 <= -10) d1 /= 10;
  if (whichDigit == 1) return d1;

  int d2 = n;
  while (d2 >= 100 || d2 <= -100) d2 /= 10;
  d2 -= d1 * 10;
  if (whichDigit == 2 && (n > 9 || n < -9)) return d2;

  int d3 = n;
  while (d3 >= 1000 || d3 <= -1000) d3 /= 10;
  d3 -= d1 * 100 + d2 * 10;
  if (whichDigit == 3 && (n > 99 || n < -99)) return d3;

  int d4 = n;
  while (d4 >= 10000 || d4 <= -10000) d4 /= 10;
  d4 -= d1 * 1000 + d2 * 100 + d3 * 10;
  if (whichDigit == 4 && (n > 999 || n < -999)) return d4;

  int d5 = n;
  while (d5 >= 10000 || d5 <= -10000) d5 /= 10;
  d5 -= d1 * 10000 + d2 * 1000 + d3 * 100 + d4 * 10;
  if (whichDigit == 5 && (n > 9999 || n <-9999)) return d5;
	
	return false;
};

My sixth sense is tingling like crazy. I think it's trying to tell me that, whatever it is your code is trying to do, there's a much, much simpler way to do it. If that's of interest to you, please share an explanation of the problem in simple English.

1 Like

consider

// -----------------------------------------------------------------------------
int
getDigit (
    int         val,
    unsigned    digitIdx)
{
    char  s [50];
    sprintf (s, "%d", val);

    if (digitIdx < strlen (s) && isdigit(s [digitIdx]))
            return (s [digitIdx] - '0');
    return -1;
}

// -----------------------------------------------------------------------------
void
test2 (
    int     val)
{
    for (int i = 0; i <= 5; i++)
        Serial.println (getDigit (val, i));
    Serial.println ();


    for (int i = 0; i <= 5; i++)
        Serial.println (getDigit (-val, i));
    Serial.println (F ("-------------"));

}

// -----------------------------------------------------------------------------
void setup () {
    Serial.begin (9600);

    test2 (1234);
}

void loop () {
    test2 (1234);
    delay (250);
}

And you should learn from this that is a poor approach. EVERYTHING in c/c++, and most other languages, is 0-based, so you should adapt to that, rather than fighting it. Your approach is just begging for exactly this kind of bug. And, you are wasting memory. First, you are creating arrays that are longer than they need to be, then creating multiple indexes for accessing them (i and count). It is wasteful, inefficient, and bug-prone, all at the same time. I fail to see ANY benefit.

The compiler can find language syntax errors, not logic errors. If you ask it to compile code that does stupid things, it will happily do it. That is one of the defining qualities of c/c++. It is "you asked for it, you got it" programming.

Idk understand we why still don't change our languages to work in more logical, but if it don't exist there must be reason why. I'll try to use [0] as first in next attempts/projects

It is perfectly logical as it is. You need to be more flexible.

For now:
You are overthinking it.
Have a walk with a dog and have a good night sleep. Don't think about your code.

For tomorrow:
Good morning.
When a binary number is handled as a decimal number, we use '/' and '%'.
A "/10" is almost as if a decimal number is shifted to the right.
A "%10" is the remainder, it is almost as if that operation gives the most right decimal digit.

The right most digit means that no shifting is needed.
The fifth digit (left most digit) can be found after shifting the number 4 times.

unsigned int number = 12345;   // the input
unsigned int x;     // the resulting decimal number
for(i=0; i<digit; i++)  // digit is the number of the requested digit 1...5
{
  x = number % 10;
  number /= 10;
}
return x;

That code in Wokwi:

Thanks, your code work like magic, cuz second after i implemented it in main project :face_exhaling:

I tried to load easier version of my code and it made my arduino a little unstable. Now i know it behaved like that cuz i put it in library without class (i found tutorial online how to do it, it's too slow or tutorial sucks)

I know i needed modulo to do it simpler, i read how it work few times and i understand how it works, but it literary never comes to my mind when i try to found solution to problem ;/

Thank u very much, now my counters look a lot smoother!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.