How do I convert an int, n
, to a string so that when I send it over the serial, it is sent as a string?
This is what I have so far:
int ledP
This is speed-optimized solution for converting int (signed 16-bit integer) into string.
This implementation avoids using division since 8-bit AVR used for Arduino has no hardware DIV instruction, the compiler translate division into time-consuming repetitive subtractions. Thus the fastest solution is using conditional branches to build the string.
A fixed 7 bytes buffer prepared from beginning in RAM to avoid dynamic allocation. Since it's only 7 bytes, the cost of fixed RAM usage is considered minimum. To assist compiler, we add register modifier into variable declaration to speed-up execution.
char _int2str[7];
char* int2str( register int i ) {
register unsigned char L = 1;
register char c;
register boolean m = false;
register char b; // lower-byte of i
// negative
if ( i < 0 ) {
_int2str[ 0 ] = '-';
i = -i;
}
else L = 0;
// ten-thousands
if( i > 9999 ) {
c = i < 20000 ? 1
: i < 30000 ? 2
: 3;
_int2str[ L++ ] = c + 48;
i -= c * 10000;
m = true;
}
// thousands
if( i > 999 ) {
c = i < 5000
? ( i < 3000
? ( i < 2000 ? 1 : 2 )
: i < 4000 ? 3 : 4
)
: i < 8000
? ( i < 6000
? 5
: i < 7000 ? 6 : 7
)
: i < 9000 ? 8 : 9;
_int2str[ L++ ] = c + 48;
i -= c * 1000;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// hundreds
if( i > 99 ) {
c = i < 500
? ( i < 300
? ( i < 200 ? 1 : 2 )
: i < 400 ? 3 : 4
)
: i < 800
? ( i < 600
? 5
: i < 700 ? 6 : 7
)
: i < 900 ? 8 : 9;
_int2str[ L++ ] = c + 48;
i -= c * 100;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// decades (check on lower byte to optimize code)
b = char( i );
if( b > 9 ) {
c = b < 50
? ( b < 30
? ( b < 20 ? 1 : 2 )
: b < 40 ? 3 : 4
)
: b < 80
? ( i < 60
? 5
: i < 70 ? 6 : 7
)
: i < 90 ? 8 : 9;
_int2str[ L++ ] = c + 48;
b -= c * 10;
m = true;
}
else if( m ) _int2str[ L++ ] = '0';
// last digit
_int2str[ L++ ] = b + 48;
// null terminator
_int2str[ L ] = 0;
return _int2str;
}
// Usage example:
int i = -12345;
char* s;
void setup() {
s = int2str( i );
}
void loop() {}
This sketch is compiled to 1,082 bytes of code using avr-gcc which bundled with Arduino v1.0.5 (size of int2str function itself is 594 bytes). Compared with solution using String object which compiled into 2,398 bytes, this implementation can reduce your code size by 1.2 Kb (assumed that you need no other String's object method, and your number is strict to signed int type).
This function can be optimized further by writing it in proper assembler code.
The solution is much too big. Try this simple one. Please provide a 7+ character buffer, no check made.
char *i2str(int i, char *buf){
byte l=0;
if(i<0) buf[l++]='-';
boolean leadingZ=true;
for(int div=10000, mod=0; div>0; div/=10){
mod=i%div;
i/=div;
if(!leadingZ || i!=0){
leadingZ=false;
buf[l++]=i+'0';
}
i=mod;
}
buf[l]=0;
return buf;
}
Can be easily modified to give back end of buffer, if you discard index 'l' and increment the buffer directly.
You can simply do:
Serial.println(n);
which will convert n
to an ASCII string automatically. See the documentation for Serial.println().
use the itoa()
function included in stdlib.h
char buffer[7]; //the ASCII of the integer will be stored in this char array
itoa(-31596,buffer,10); //(integer, yourBuffer, base)
Here below is a self composed myitoa() which is by far smaller in code, and reserves a FIXED array of 7 (including terminating 0) in char *mystring, which is often desirable. It is obvious that one can build the code with character-shift instead, if one need a variable-length output-string.
void myitoa(int number, char *mystring) {
boolean negative = number>0;
mystring[0] = number<0? '-' : '+';
number = number<0 ? -number : number;
for (int n=5; n>0; n--) {
mystring[n] = ' ';
if(number > 0) mystring[n] = number%10 + 48;
number /= 10;
}
mystring[6]=0;
}
Use like this:
String myString = String(n);
You can find more examples here.