Есть шанс сделать это быстрее, чем справочная таблица, если арифметические вычисления по какой-то причине быстрее, чем доступ к памяти. Это может быть возможно, если вычисления векторизованы (PPC AltiVec или Intel SSE) и / или если другим частям программы необходимо использовать каждый бит кэш-памяти.
Если коэффициент расширения = 3, необходимо всего 7 инструкций:
out = (((in * 0x101 & 0x0F00F) * 0x11 & 0x0C30C3) * 5 & 0x249249) * 7;
Или другой вариант, с 10 инструкциями:
out = (in | in << 8) & 0x0F00F;
out = (out | out << 4) & 0x0C30C3;
out = (out | out << 2) & 0x249249;
out *= 7;
Для других коэффициентов расширения> = 3:
unsigned mask = 0x0FF;
unsigned out = in;
for (scale = 4; scale != 0; scale /= 2)
{
shift = scale * (N - 1);
mask &= ~(mask << scale);
mask |= mask << (scale * N);
out = out * ((1 << shift) + 1) & mask;
}
out *= (1 << N) - 1;
Или другая альтернатива для коэффициентов расширения> = 2:
unsigned mask = 0x0FF;
unsigned out = in;
for (scale = 4; scale != 0; scale /= 2)
{
shift = scale * (N - 1);
mask &= ~(mask << scale);
mask |= mask << (scale * N);
out = (out | out << shift) & mask;
}
out *= (1 << N) - 1;
Значения
shift
и mask
лучше рассчитывать до обработки битового потока.