Your solution generates the digits in the right order directly, but at a cost of a variable divide (v / dgtIdx
), a variable modulo (which has the same or greater cost than a divide), and a divide by 10. That is three expensive operations.
It may be less expensive to generate the digits from the least-significant digit first, then reverse the digits after. That will then require only a divide by 10 and a modulo 10 operation. Using the solution at Divide by 10 using bit shifts? and modifying it to obtain the remainder in the same operation as the quotient:
uint32_t div10_rem( uint32_t dividend, int* remainder )
{
uint32_t quotient = (uint32_t)((0x1999999Aull * dividend) >> 32) ;
*remainder = dividend - (quotient * 10) ;
return quotient ;
}
Then the conversion to a displayable decimal string might be:
char* int2dec( uint32_t val, char* buffer )
{
char reverse_digits[10] = {0} ;
uint32_t u = val ;
size_t digit_count = 0 ;
while( u > 0 )
{
int d = 0 ;
u = div10_rem( u, &d ) ;
reverse_digits[digit_count] = d + '0' ;
digit_count++ ;
}
buffer[digit_count] = '\0' ;
size_t i = 0 ;
for( size_t i = 0; i < digit_count; i++ )
{
buffer[i] = reverse_digits[digit_count - i - 1] ;
}
return buffer ;
}
Then an example usage:
char buffer[11] ;
printf( "%s", int2dec( val, buffer) ) ;
It is possible to avoid the digit reversal if a static buffer is suitable:
#define MAX_DIGITS 10
const char* int2dec( uint32_t val )
{
static char digits[MAX_DIGITS + 1] = {0} ;
uint32_t u = val ;
size_t digit_index = MAX_DIGITS - 1 ;
while( u > 0 )
{
int d = 0 ;
u = div10_rem( u, &d ) ;
digits[digit_index] = d + '0' ;
digit_index-- ;
}
return &digits[digit_index + 1] ;
}
Then, for example:
printf( "%s", int2dec( val ) ) ;