Just discovered this. When I cast an int to a char inside a Serial.print statement it costs way less program memory. I'm not sure why. Could someone explain this to me? In the following example the difference is 228 bytes!
Serial.print(1); // 1676 bytes program storage space. 184 bytes of dynamic memory.
Serial.print((char) (48 + 1)); // 1448 bytes program storage space. 184 bytes of dynamic memory.
EDIT: Adding from different comments:
Serial.print('1'); // Sketch uses 1448 bytes program memory, 184 bytes dynamic memory
Serial.write(48 + 1); // Sketch uses 1448 bytes program memory, 184 bytes dynamic memory
EDIT: For an int > 9, adding quotes in following example saves 218 bytes program memory but adds 4 bytes to dynamic memory usage.
Serial.print(123); // 1676/184 bytes
Serial.print("123"); // 1458/188 bytes
Serial.print(String(123)); // 2772/194 bytes
EDIT2: Max digits in Arduino-uno int is 5(?). You save 80 bytes by converting it to a char array, in comparison to just printing the integer:
Serial.print(12345); // 1676/184 bytes
char digits[5];
int number = 12345;
for (int i = 4; i >= 0; i--) {
digits[i] = (number %10) + 48;
number /= 10;
}
Serial.print(digits); // 1596/184 bytes
To test for yourself, uncommenting one or the other:
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.print(1); // uses 1676/184 bytes
//. Serial.print((char) (48 + 1)); // uses 1448/184 bytes
// Serial.print('1'); // uses 1448/184 bytes
// Serial.write(48 + 1); // 1448/184 bytes
// Serial.print(123); // 1676/184 bytes
// Serial.print("123"); // 1458/188 bytes
// Serial.print(String(123)); // 2772/194 bytes
// Serial.print(12345); // 1676/184 bytes | 1676/184
// Serial.print("12345"); // 1458/188 bytes | 1460/190
// char buff[5];
// itoa(12345, buff, 10);
// Serial.print(buff); // 1604/184 bytes
char digits[5];
int number = 12345;
for (int i = 4; i >= 0; i--) {
digits[i] = (number %10) + 48;
number /= 10;
}
Serial.print(digits); // 1596/184 bytes
}
void loop() {
// put your main code here, to run repeatedly:
}
EDIT: Second question: Shouldn't this be optimised somehow? Or should I always take care of this myself? And why/how? ;)
*the chars 0-9 have a decimal value of 48-57 in the Ascii table, hence (char)(48 + 0-9) prints 0-9
1 Answer 1
The difference is simply this:
- Print this character
and
- Interpret this integer as a sequence of digits, work out the ASCII characters that represent each digit in turn, and print them.
As you can see even just writing out what the second one does takes more words. Printing an integer is a lot more work than just printing one character. Think about what it takes to print the value 2034578 and how you would do that given that you can only output individual numbers 0-9 and the data isn't stored as the numbers 0-9 but a series of just 0 and 1...
It takes work. Lots of work.
-
So why not cast it to a char in the background then. As that takes less work, lots of less work ;)Gaai– Gaai2022年10月11日 14:42:40 +00:00Commented Oct 11, 2022 at 14:42
-
2@Gaai, because that is not what the
int
overload of.print()
does in the general case. You cannot print.print(123);
correctly with a single cast and addition. You're invoking the machinery that allows for correct printing of123
even if you only ask for1
, and so you pay for that. The answer is correct.timemage– timemage2022年10月11日 14:54:15 +00:00Commented Oct 11, 2022 at 14:54 -
print is a convinience function for easily printing different types as ASCII text. If all you want is to print a single character, then you shouldn't use print, but write. You yourself have to chosse the correct tool for your workchrisl– chrisl2022年10月11日 15:01:53 +00:00Commented Oct 11, 2022 at 15:01
-
@chrisl Ah yes. This makes sense. That should be added to the answer! Serial.write(1) costs the same as the single char print.Gaai– Gaai2022年10月11日 15:09:47 +00:00Commented Oct 11, 2022 at 15:09
-
1@Gaai The first bullet point "print this character" is the single character that you are opn about.Majenko– Majenko2022年10月11日 15:32:16 +00:00Commented Oct 11, 2022 at 15:32
Explore related questions
See similar questions with these tags.
.print('1')
and.print((char) 1)
too