Есть ли способ записать функцию журнала (база 2)?
Язык C имеет 2 встроенных функции - >>
1. logкоторый является основанием e.
2. log10база 10;
Но мне нужна функция журнала базы 2, как это вычислить.
Есть ли способ записать функцию журнала (база 2)?
Язык C имеет 2 встроенных функции - >>
1. logкоторый является основанием e.
2. log10база 10;
Но мне нужна функция журнала базы 2, как это вычислить.
Ответы:
У C99 есть log2(как log2fи log2lдля float и long double).
Если вы ищете интегральный результат, вы можете просто определить самый высокий бит, установленный в значении, и вернуть его позицию.
Integer.highestOneBit(int)метода Java ):i |= (i >> 1); i |= (i >> 2); i |= (i >> 4); i |= (i >> 8); i |= (i >> 16); return i - (i >>> 1);
while (i >>= 1) { ++l; }
i>>32. Но поскольку в Java есть только 32-битные целые числа, это нормально. Для C / C ++ это необходимо учитывать.
#define M_LOG2E 1.44269504088896340736 // log2(e)
inline long double log2(const long double x){
return log(x) * M_LOG2E;
}
(умножение может быть быстрее деления)
Как указано на http://en.wikipedia.org/wiki/Logarithm :
logb(x) = logk(x) / logk(b)
Которое значит что:
log2(x) = log10(x) / log10(2)
log()реализации, он этого не сделает. Виноват.
log10()это функция, определенная в стандарте C, компилятор может обработать ее «специально», включая предварительное вычисление результата, что, как я считаю, было предложением @Johannes?
log10(2)константу.
Если вы хотите сделать это быстро, вы можете использовать таблицу поиска, как в Bit Twiddling Hacks (только целочисленный log2).
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];
Кроме того, вам следует взглянуть на встроенные методы вашего компилятора, например, _BitScanReverseкоторые могут быть быстрее, потому что они могут полностью вычисляться аппаратно.
Также обратите внимание на возможные дубликаты. Как сделать целое число log2 () в C ++?
uint16_t log2(uint32_t n) {//but truncated
if (n==0) throw ...
uint16_t logValue = -1;
while (n) {//
logValue++;
n >>= 1;
}
return logValue;
}
В основном то же, что и у tomlogic .
Вы должны включить math.h (C) или cmath (C ++). Конечно, имейте в виду, что вы должны следовать математике, которую мы знаем ... только числа> 0.
Пример:
#include <iostream>
#include <cmath>
using namespace std;
int main(){
cout<<log2(number);
}
Мне нужно было иметь большую точность, чем просто положение самого старшего бита, а в микроконтроллере, который я использовал, не было математической библиотеки. Я обнаружил, что простое использование линейного приближения между значениями 2 ^ n для аргументов с положительным целым числом работает хорошо. Вот код:
uint16_t approx_log_base_2_N_times_256(uint16_t n)
{
uint16_t msb_only = 0x8000;
uint16_t exp = 15;
if (n == 0)
return (-1);
while ((n & msb_only) == 0) {
msb_only >>= 1;
exp--;
}
return (((uint16_t)((((uint32_t) (n ^ msb_only)) << 8) / msb_only)) | (exp << 8));
}
В моей основной программе мне нужно было вычислить N * log2 (N) / 2 с целочисленным результатом:
temp = (((uint32_t) N) * приблизительно_log_base_2_N_times_256) / 512;
и все 16-битные значения никогда не отклонялись более чем на 2%
Все приведенные выше ответы верны. Этот мой ответ ниже может быть полезен, если кому-то это нужно. Я видел это требование во многих вопросах, которые мы решаем с помощью C.
log2 (x) = logy (x) / logy (2)
Однако, если вы используете язык C и хотите получить целочисленный результат, вы можете использовать следующее:
int result = (int)(floor(log(x) / log(2))) + 1;
Надеюсь это поможет.
Улучшенная версия того, что сделал Устаман Сангат
static inline uint64_t
log2(uint64_t n)
{
uint64_t val;
for (val = 0; n > 1; val++, n >>= 1);
return val;
}