Đây là giải pháp tối ưu hóa tốc độ để chuyển đổi int (số nguyên 16 bit đã ký) thành chuỗi.
Triển khai này tránh sử dụng phân chia vì AVR 8 bit được sử dụng cho Arduino không có hướng dẫn DIV phần cứng, trình biên dịch dịch thành các phép trừ lặp đi lặp lại tốn nhiều thời gian. Vì vậy, giải pháp nhanh nhất là sử dụng các nhánh có điều kiện để xây dựng chuỗi.
Bộ đệm 7 byte cố định được chuẩn bị từ đầu trong RAM để tránh phân bổ động. Vì nó chỉ có 7 byte, chi phí sử dụng RAM cố định được coi là tối thiểu. Để hỗ trợ trình biên dịch, chúng tôi thêm công cụ sửa đổi đăng ký vào khai báo biến để thực thi tăng tốc.
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() {}
phác thảo này được biên soạn để 1.082 byte mã sử dụng avr-gcc mà đi kèm với Arduino v1.0.5 (kích thước của chức năng int2str chính nó là 594 byte). So với giải pháp sử dụng đối tượng String được biên dịch thành 2.398 byte, việc triển khai này có thể giảm kích thước mã của bạn xuống 1,2 Kb (giả sử rằng bạn không cần phương thức đối tượng String khác và số của bạn là nghiêm ngặt đối với loại int đã ký).
Chức năng này có thể được tối ưu hóa thêm bằng cách viết nó vào mã lắp ráp thích hợp.
Không sprintf trên Arduino? – Pubby
? Tất cả các ý kiến đã được ở đây đã biến mất .... những gì đã xảy ra? – user947659
@Pubby "printf() làm cho đối tượng thực thi của bạn ~ 1000 byte lớn hơn, vì vậy bạn có thể không muốn sử dụng nó nếu kích thước là một vấn đề." http://playground.arduino.cc/Main/Printf –