Questa soluzione è ottimizzata per la velocità per convertire int (numero intero a 16 bit con segno) in stringa.
Questa implementazione evita l'utilizzo della divisione poiché l'AVR a 8 bit utilizzato per Arduino non ha un'istruzione DIV hardware, il compilatore traduce la divisione in sottrazioni ripetitive che richiedono molto tempo. Quindi la soluzione più veloce sta usando i rami condizionali per costruire la stringa.
Un buffer 7 byte fisso preparato dall'inizio nella RAM per evitare l'allocazione dinamica. Poiché sono solo 7 byte, il costo dell'utilizzo fisso della RAM è considerato minimo. Per aiutare il compilatore, aggiungiamo il modificatore del registro nella dichiarazione delle variabili per accelerare l'esecuzione.
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() {}
Questo schizzo è compilato per 1.082 byte di codice utilizzando avr-gcc che impacchettato con Arduino v1.0.5 (dimensione della funzione int2str stessa è 594 byte). Rispetto alla soluzione utilizzando l'oggetto String che è stato compilato in 2.398 byte, questa implementazione può ridurre le dimensioni del codice di 1,2 Kb (presupponendo che non sia necessario alcun altro metodo di oggetto String e il proprio numero sia rigoroso rispetto al tipo int firmato).
Questa funzione può essere ulteriormente ottimizzata scrivendola nel codice assembler corretto.
No sprintf su Arduino? – Pubby
? Tutti i commenti che c'erano qui sono andati .... cosa è successo? – user947659
@Pubby "printf() rende il tuo oggetto eseguibile ~ 1000 byte più grande, quindi potresti non volerlo usare se la dimensione è un problema." http://playground.arduino.cc/Main/Printf –