Ah, now I see why you understand.
I think the base 1 case just needs to avoid crashing and give an indication of a bug.
Printing the string "00000000000000000000000000" is a big clue.
On compiler optimization. You need to use large sketches to see if a change is worth doing. The compiler does a pretty global optimization of a class. Here are some examples for Print.
I used a large sketch with a lot of print/println calls to estimate the 100 byte savings for the new printNumber(). The results were old function 7492 bytes new function 7388 bytes. This was consistent with several other large sketches.
Things are not so clear with a very simple sketch. For this sketch:
void setup() {
Serial.begin(9600);
Serial.print(1234567UL);
}
void loop() {}
You get old 1846, new 1696 for a savings of 150 bytes.
If you change the "UL" to "L"
void setup() {
Serial.begin(9600);
Serial.print(1234567L);
}
void loop() {}
You get old 1816, new 1774 for a savings of 42 bytes.
I have not dumped the assembly listing to see why.
What I have learned is that simple examples are dangerous for design decisions.