I am trying to split a number into single digits, so I can change it using button input. The code I made works fine for every number from 000.001 until 909.999. But if I put 4 or higher at the 10 position it messes up. First thing I though was overflow. But you can put a 9 in the 100 position no problem. Position 3 in the array it the placeholder for the decimal point.
The code below outputs this:
9 3 9 0 9 9 9
0 4 65 0 660 6561 32767
Tried on Uno and Nano Every.
int menunumber[7] = {0,0,0,0,0,0,0};
void setup() {
Serial.begin(9600);
}
void loop() {
delay(1000);
parsenumber(939.999);
parsenumber(40.009);
while(1) delay(1000);
}
void parsenumber(double number){
number = number * 1000;
menunumber[0] = number/100000; number -= menunumber[0]*100000;
menunumber[1] = number/10000; number -= menunumber[1]*10000;
menunumber[2] = number/1000; number -= menunumber[2]*1000;
menunumber[4] = number/100; number -= menunumber[4]*100;
menunumber[5] = number/10;
menunumber[6] = number - menunumber[5]*10;
for(int i=0;i<7;i++){
Serial.print(menunumber[i]);
Serial.print(" ");
}
Serial.println(" ");
}
please show the code where you are attempting to debug your logic! I see no attempt in what you are showing. Do you know there is a maximum value that your “int” can hold?
Might work better to convert the number to a long integer first, to avoid any rounding from the floats. Remember an UNO, and possibly the Nano Every, does not support double.
I might even try converting to ASCII with dtostrf() since you want to display the results.
What is the largest number that the type of menunumber can hold?
Is 100000 greater than that number?
If yes, will menunumber[0] * 100000 produce a useful or useless result if menunumber[0] is anything other then zero?
What would one possible solution be to getmenunumber[0] * 100000 to produce a useful result if menunumber[0] is anything other then zero?
Hint: it might also be a productive use of time to consider what range of values menunumber[1] * 10000 can produce and whether or not they can be larger than the type of menunumber.
Yes, I get it now. Menunumber is an int and 10000 is an int, but 40000 does not fit into int. But 100000 is already a long, so this line works. Somedays I am really annoyed by how C++ works.
The conversion will be a bit more involved if it needs to work with negative numbers.
It is a bit simpler if you work from right to left. Could even be a loop if the placeholder for the decimal point is removed, or the number is adjusted to put a 0 in that position.
void parsenumber(double numberDouble) {
unsigned long number = numberDouble * 1000; //assumes only positive numbers
menunumber[6] = number % 10; number /= 10;
menunumber[5] = number % 10; number /= 10;
menunumber[4] = number % 10; number /= 10;
menunumber[2] = number % 10; number /= 10;
menunumber[1] = number % 10; number /= 10;
menunumber[0] = number % 10; number /= 10;
I thought it might be easier to read without all the Serial.print lines and you guys would see the mistake immediatly, which you did. I did see negative number for the multiplacation and thought overflow, but was confused because it worked for in the first line which has even bigger numbers.
I had several programming lectures at Uni, including C++, but they were mostly about algorithms, not how the language actually works. I also had to attended the main lecture for computer science students, where we learned a lot about graph theorie. Now everybody uses pascal which wasnt even invented when I was studying.
I think it would be better if the operation was done with type of the variable left of the =. Easier to debug and I wouldnt have to declare my variables bigger then they need to be.
Thank you, I will use that, looks much better than my code.
The first line has 100000, which the compiler understands requires a long integer.
To me that would be much worse. Just think of the confusion if you specified a mathematical operation using floating point numbers, then the compiler converted everything to byte before doing the calculation because that is the type of variable the result is stored in.