Наиболее эффективным способом может быть использование метода быстрого логарифмирования, аналогичного используемому для определения старшего бита, установленного в целом числе.
size_t printed_length ( int32_t x )
{
size_t count = x < 0 ? 2 : 1;
if ( x < 0 ) x = -x;
if ( x >= 100000000 ) {
count += 8;
x /= 100000000;
}
if ( x >= 10000 ) {
count += 4;
x /= 10000;
}
if ( x >= 100 ) {
count += 2;
x /= 100;
}
if ( x >= 10 )
++count;
return count;
}
Эта (возможно, преждевременная) оптимизация занимает 0,65 с для 20 миллионов вызовов на моем нетбуке; итеративное деление, такое как у zed_0xff, занимает 1,6 с, рекурсивное деление, такое как Кангкан, занимает 1,8 с, а использование функций с плавающей запятой (код Джордана Льюиса) - колоссальные 6,6 с. Использование snprintf занимает 11,5 с, но даст вам размер, необходимый snprintf для любого формата, а не только для целых чисел. Джордан сообщает, что на его процессоре не поддерживается порядок времени, что делает число с плавающей запятой быстрее, чем у меня.
Возможно, проще всего спросить у snprintf длину печати:
#include <stdio.h>
size_t printed_length ( int x )
{
return snprintf ( NULL, 0, "%d", x );
}
int main ()
{
int x[] = { 1, 25, 12512, 0, -15 };
for ( int i = 0; i < sizeof ( x ) / sizeof ( x[0] ); ++i )
printf ( "%d -> %d\n", x[i], printed_length ( x[i] ) );
return 0;
}