Каков наилучший способ рассчитать 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) рассчитаны по отношению к той же базе.

Другие вопросы по тегам