Каков наилучший способ рассчитать log(base2) любого числа?
Мне нужно найти log(base2) любого числа в программировании ядра Linux. Есть ли встроенная функция для этой операции? Если не как рассчитать?
2 ответа
Если вам достаточно целочисленного результата, вы можете делить его несколько раз на 2. Что-то вроде
int logFunc(unsigned int x)
{
int log = -1;
while(x) {
log++;
x >>= 1;
}
return log;
}
Если вам нужен fp ops, вы должны прочитать это:
[...] если бы вопрос был "могу ли я просто использовать FP в ядре", то ответ - все еще громкое НЕТ, так как другие архитектуры могут вообще не поддерживать его.
Linus
Также вы можете взглянуть на: Использование плавающей запятой в ядре Linux
РЕДАКТИРОВАТЬ: Если вам нужна более быстрая версия, вы можете прочитать Bit Twiddling Hacks - Шон Эрон Андерсон
uint32_t v; // find the log base 2 of 32-bit v
int r; // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
};
v |= v >> 1; // first round down to one less than a power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27];
По определению логарифм числа N в любом конкретном основании B равен log(N)/log(B)
, где log()
может быть либо натуральный логарифм (основание e
), или любая другая база (например, база 10), если оба log(N)
а также log(B)
рассчитаны по отношению к той же базе.