Ваш код log10 / floor отлично читается, и его производительность, скорее всего, будет меньше, чем при форматировании строки, которое вы впоследствии будете использовать для вывода.
Однако предположим, что вам действительно нужна производительность ...
Обратите внимание, что log10 (x) == log2 (x) / log2 (10) == log2 (x) * 1 / log2 (10)
1 / log2 (10) является константой
log2 (x) обычно может быть дешево выполнен в целочисленном конвейере на современных архитектурах с использованием инструкций, таких как CLZ или битовый хаддлинг , что дает число от 0 до 63 для 64-битного целого числа Это вписывается в 6 бит, оставляя нам до 58 бит после радикальной точки, пригодной для арифметики с фиксированной точкой в 64-битном типе.
Таким образом, мы можем использовать арифметику с фиксированной запятой, чтобы найти log10:
unsigned long long integer_log10( unsigned long long _in )
{
unsigned long long log10fp6x58 = 0x134413509f79ff0llu; // (unsigned long long) (double(1llu<<58) / log2(10.0))
return (((integer_log2(_in)) * log10fp6x58)+(1llu<<57)) >> 58;
}
Реализация integer_log2 зависит от компилятора / платформы; например на GCC / PowerPC это
unsigned long long integer_log2( unsigned long long _in )
{
return 63 - __cntlzd(_in);
}
Этот подход можно обобщить для нахождения логарифма любой базы, просто вычислите соответствующую константу, как описано выше.