i have a character array into which i accumulate some numbers and then convert that string into an integer. every thing worked fine until i tried a number greater than 32767 (which is pretty specific) in which case it dumps out "4294934528" no matter what the input number at that point. i assume, as i am coping into a long, that my issue is my lack of understanding of what atoi does and how it does it since there should be plenty of room.
i'd appreciate your input..
char ygoal[10];
Serial.println(ygoal);
unsigned long ygoalie = atoi(ygoal);
Serial.println(ygoalie);
32767 is the highest positive value that can be held by a signed 16 bit int, but you are trying to convert a larger value to a 32 bit unsigned long value, so no wonder it does not work
Try using the atol() function instead. It will convers a string to a long integer as long as the string is correctly terminated with a zero, which assume you are doing, or are you ?
as the i in its name indicate,atoi() converts to an integer and an integer on a small 8 bit arduino is stored on 2 bytes, so as @UKHeliBob said, 32767 is the max value you can represent and return.
if you want to decode a long (and store in a long) then you need to use atol()
Note that those 2 functions are not great as there is no way to know if they failed to read something correctly: They will return a weird number as you saw if you overflow and zero (even if you did not enter 0) if no number could be read. I would suggest you actually use strtol() to detect errors.
right, right.
i see the error of my ways.
you know, i even looked it up and saw that it meant integer. right over my head.
thanks for all the help, fellas.
atol() works great for what i need now. i have done nothing special with zeros, but all seems well so far. we shall yet see what the future holds. profanity and great frustration, no doubt..
The 2^7 2^8, 2^15, 2^16, 2^31, and 2^32 numbers are important for dealing with integers on computers. If you see something unexpected near those numbers, it's probably some sort of type/rollover/casting issue.
No one would tell you to sit down and memorize a bunch of numbers, but over time it is nearly impossible not to pick up a few, a few that will always pop up in circumstances like these.
Traditionally, by the name integer, I understand a decimal number with no fractional part but composed of digits: 0 to 9 and symbols: + and -.
In the context of atoi() function, the letter i says to me that the return value of the atoi() function is of type int (range: 0x8000 to 0x7FFF = -32768 to 32767). So, I am allowed to convert ASCII coded data items of the range -32768 to 32767 into a single data item (range: 0x8000 to 0x7FFF) whose decimal image can be presented using DEC base. For example: Test Sketch:
char myData[10];
void setup()
{
Serial.begin(9600);//UNO's UART is active
}
void loop()
{
byte n = Serial.available(); //n = 1
if ( n != 0)
{
byte m = Serial.readBytesUntil('\n', myData, sizeof myData - 1);//arg3 = arraySize
myData[m] = '\0'; //null byte
int x = atoi(myData);
Serial.println(x, DEC);
}
}
That’s where it’s tricky. On a 8 bit MCU you are right because an int is represented with 16 bits but on a 32 bit MCU int uses 32 bits to represent its value so you get much larger range, from -231 to 231 - 1, which is from -2,147,483,648 to 2,147,483,647.