Given an (unsigned) integer, what is the generally fastest way to convert it into a string that contains its decimal representation?
The naïve way of doing that
I believe integer division by a constant is as fast as doing a multiplication because the compiler optimizes integer division to integer multiplication for constant divisors. This is a heavy duty math trick performed by most optimizing compilers.
The generally fastest way is to index into a big enough array of pointers to strings. One array lookup, one pointer dereference. It's heavy on memory usage, though... That's the nature of engineering tradeoffs. How fast is fast enough?
The MS version of printf does it the "naïve" way (after setting up a bunch of variables based on the optional flags):
while (precision-- > 0 || number != 0) {
digit = (int)(number % radix) + '0';
number /= radix; /* reduce number */
if (digit > '9') {
/* a hex digit, make it a letter */
digit += hexadd;
}
*text.sz-- = (char)digit; /* store the digit */
}
The fastest approach on all but the simplest (e.g. 8-bit) microcontrollers is to use division, but reduce the number of divisions by generating several digits at once.
You will find very highly optimized code in answers to my question here. Using it in C should be a trivial edit to eliminate std::string
-- there are no C++ features used in the actual conversion. The core is
while(val>=100)
{
int pos = val % 100;
val /= 100;
*(short*)(c-1)=*(short*)(digit_pairs+2*pos); // or use memcpy
c-=2;
}
while(val>0)
{
*c--='0' + (val % 10);
val /= 10;
}
I also provided an optimized division-free code for 8-bit micros, similar to the idea shown in the code in the question, but without loops. It ends up with a lot of code like this:
if (val >= 80) {
ch |= '8';
val -= 80;
}
else if (val >= 40) {
ch |= '4';
val -= 40;
}
if (val >= 20) {
ch |= '2';
val -= 20;
}
if (val >= 10) {
ch |= '1';
val -= 10;
}