Go Down

Topic: Update single digit in an int (Read 324 times) previous topic - next topic

Slyke

Hello,

Been struggling with this for a while now.

I'm trying to create a function like:
Quote
unsigned int setDigit(unsigned int inputNumber, byte newDigit, byte loc, byte exponent)
It should basically accept an unsigned int, a byte, a location and the exponent. It should then update whatever number is at location loc to the newDigit byte that's passed in.

I'm using this on a display 4x7 segment display that will show a number either in dec or hex (hence the exponent parameter) and the user can change a single digit that's being displayed by pressing a button to move the "cursor" left or right, and then press a number on a keypad to set that digit.

I do have a semi working version of this code, but having problems dealing with the edge cases. For example, when the address is 0 all my logic fails.

I've tried breaking the number up into a string and setting the index to the passed byte, but this also fails.

Here are my 2 attempts at it:

Non-string version:
Code: [Select]

unsigned int setDigit(unsigned int inputNumber, byte newDigit, byte loc, byte exponent) {
  const byte maxSize = 32;

  byte numberSize = (inputNumber == 0 ? 1 : 0);
  unsigned int nSize = inputNumber;
  while (nSize != 0 && numberSize < maxSize) {
    nSize /= exponent;
    numberSize++;
  }
 
  if (loc > maxSize || loc > numberSize || loc < 0) {
    return inputNumber;
  }
 
  char *numberArray = calloc((int)numberSize, sizeof(char));

  unsigned int i = 0;
  unsigned int nCount = inputNumber;
 
  while (nCount != 0 && i < numberSize) {
    numberArray[i] = nCount % exponent;
    nCount /= exponent;
    i++;
  };

  numberArray[loc] = (newDigit % exponent);

  int output = 0;
 
  for (byte j = 0; j < numberSize; j++) {
    output = exponent * output + numberArray[j];
  }
 
  if (numberArray) {
    free(numberArray);
  }
 
  return output;
}



String version:
Code: [Select]

unsigned int setDigit(unsigned int inputNumber, byte newDigit, byte loc, byte exponent) {
  const byte maxSize = 32;

  String inputString = "";

  if (loc > maxSize || loc < 0) {
    if (SERIAL_ERRORS && Serial) {
      Serial.print("\nsetDigit(): Error: Index out of bounds.\n");
    }
    return inputNumber;
  }

  char temp[maxSize] = {0};
  sprintf(temp, "%d", inputNumber);
  inputString.concat(temp);

  char replaceNum[maxSize] = {0};
  sprintf(replaceNum, "%01d", (newDigit % exponent));
 
 
  inputString[loc] = replaceNum;
  unsigned int output = 0;

  output = strtol(inputString.c_str(), NULL, exponent + 1);
  return output;
}

PaulS

Quote
For example, when the address is 0 all my logic fails.
The term "address" never appears in your code, so it isn't clear what you are talking about.

If you have a value, such as 12345, and you wish to change the 3 to a 7, simply subtract 3 * x * x and add 7 * x * x, where x is either 10 or 16.

I have no idea why you appear to be using the term exponent when you mean base.
The art of getting good answers lies in asking good questions.

christop

There may be a better way to do it, but here's my attempt at implementing setDigit (lightly tested):
Code: [Select]

unsigned int setDigit(unsigned int inputNumber, byte newDigit, byte pos, byte radix) {
        unsigned int posValue = 1;
        while (pos > 0) {
                posValue *= radix;
                --pos;
        }
        return inputNumber + ((int)newDigit - (int)((inputNumber / posValue) % radix)) * posValue;
}

Slyke

Hey @PaulS, sorry for the confusion. I typed it after working on it for a few hours before bed. The address is the input number. I'm passing the address in as the inputNumber when calling this function. The return of the function is then set as the address.

The main issues I'm having with this is say the address is an int of address 0, but the user wants to change the second digit.

Thank you @christop! I'm going to give your code a try once I get home. Going to go back over mine to see what I was missing too.

Paul_KD7HB

The Arduino integers are binary, not decimal, so I don't get what you are trying to accomplish.

Paul

Robin2

#5
Mar 21, 2019, 10:51 pm Last Edit: Mar 22, 2019, 10:21 am by Robin2
I agree with @Paul_KD7HB. The concept of "single digit in an int" is meaningless.

If the data was text in a char array it would be easy to change any of the characters - for example

Code: [Select]
myCharNumber[] = "12345";

myCharNumber[2] = '7';


will change it to 12745

...R

Edit .. added single quotes around the 7 - apologies for any confusion.
Two or three hours spent thinking and reading documentation solves most programming problems.

GolamMostafa

#6
Mar 22, 2019, 05:36 am Last Edit: Mar 22, 2019, 06:51 am by GolamMostafa
Code: [Select]
myCharNumber[] = "12345";

myCharNumber[2] = 7;


will change it to 12745
No! It changes to what is shown in the following screenshot.

sherzaad

#7
Mar 22, 2019, 08:54 am Last Edit: Mar 22, 2019, 08:55 am by sherzaad
I agree with @Paul_KD7HB. The concept of "single digit in an int" is meaningless.

If the data was text in a char array it would be easy to change any of the characters - for example

Code: [Select]
myCharNumber[] = "12345";

myCharNumber[2] = 7;


will change it to 12745

...R
@ Robin
I think you meant:

myCharNumber[2] = '7'; //will change it to 12745 if myCharNumber is printed to serial monitor

 ;)



GolamMostafa

#8
Mar 22, 2019, 09:58 am Last Edit: Mar 22, 2019, 10:12 am by GolamMostafa
@ Robin
I think you meant:

myCharNumber[2] = '7'; //will change it to 12745 if myCharNumber is printed to serial monitor

No! @Rabin2 has not written 'myCharNumber[2] = 7;' to mean 'myCharNumber[2] = '7';'. Wait and see what @Rabin2 says about it.  


Robin2

#10
Mar 22, 2019, 10:24 am Last Edit: Mar 22, 2019, 10:25 am by Robin2
No! It changes to what is shown in the following screenshot.
Thank you for spotting my mistake - I have corrected it.

Please note that a comment such as that made by @sherzaad in Reply #7 is more helpful for other readers.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

GolamMostafa

#11
Mar 22, 2019, 10:45 am Last Edit: Mar 22, 2019, 10:50 am by GolamMostafa
Thank you for spotting my mistake - I have corrected it.

Please note that a comment such as that made by @sherzaad in Reply #7 is more helpful for other readers.
@Rabin2 is one of the helpful posters of this Forum from both qualitative and quantitative point of views; therefore, we have to be patient to hear from him first before any 'hard comment/message' is passed onto him.

Thank you for the reply.

neiklot

#12
Mar 22, 2019, 10:50 am Last Edit: Mar 22, 2019, 11:07 am by neiklot

GolamMostafa

#13
Mar 22, 2019, 11:22 am Last Edit: Mar 22, 2019, 11:26 am by GolamMostafa
@Rabin2 is one [...].
Robin2....
This is not a problem for @Robin2; it is a forumName; I will write it properly next time.


Robin2

#14
Mar 22, 2019, 01:18 pm Last Edit: Mar 22, 2019, 04:01 pm by Robin2
@Rabin2 is one of the helpful posters of this Forum from both qualitative and quantitative point of views; therefore, we have to be patient to hear from him first before any 'hard comment/message' is passed onto him.
Just because I post frequently does not mean that I am less likely to make silly mistakes. I appreciate it when people point them out early and clearly so I can correct them.

...R

Edit to insert "mean"
Two or three hours spent thinking and reading documentation solves most programming problems.

Go Up