Cómo escribir log base (2) en c / c ++

¿Hay alguna forma de escribir la función de registro (base 2)?

El lenguaje C tiene 2 funciones integradas – >>

1. log que es base e.

2. log10 base 10;

Pero necesito la función de registro de la base 2. Cómo calcular esto.

Matemática simple:

log 2 ( x ) = log y ( x ) / log y (2)

donde y puede ser cualquier cosa, que para las funciones de registro estándar es 10 o e .

Si busca un resultado integral, puede determinar el bit más alto establecido en el valor y devolver su posición.

 #define M_LOG2E 1.44269504088896340736 // log2(e) inline long double log2(const long double x){ return log(x) * M_LOG2E; } 

(la multiplicación puede ser más rápida que la división)

C99 tiene log2 (así como log2f y log2l para flotación y doble larga).

Como se indica en http://en.wikipedia.org/wiki/Logarithm :

 logb(x) = logk(x) / logk(b) 

Lo que significa que:

 log2(x) = log10(x) / log10(2) 
 log2(int n) = 31 - __builtin_clz(n) 

Si quieres hacerlo rápido, puedes usar una tabla de búsqueda como en Bit Twiddling Hacks (integer log2 solamente).

 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]; 

Además, debería echar un vistazo a los métodos _BitScanReverse comstackción, como _BitScanReverse que podrían ser más rápidos porque pueden computarse completamente en hardware.

Eche también un vistazo a posibles duplicados ¿Cómo hacer un entero log2 () en C ++?

 log2(x) = log10(x) / log10(2) 
 uint16_t log2(uint32_t n) {//but truncated if (n==0) throw ... uint16_t logValue = -1; while (n) {// logValue++; n >>= 1; } return logValue; } 

Básicamente lo mismo que Tomlogic .

Debe incluir math.h (C) o cmath (C ++) Por supuesto, tenga en cuenta que debe seguir las matemáticas que conocemos … solo números> 0.

Ejemplo:

 #include  #include  using namespace std; int main(){ cout< 

Necesitaba tener más precisión que solo la posición del bit más significativo, y el microcontrolador que estaba utilizando no tenía biblioteca matemática. Descubrí que el uso de una aproximación lineal entre 2 ^ n valores para los argumentos de valor entero positivo funcionó bien. Aquí está el código:

 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)); } 

En mi progtwig principal, necesitaba calcular N * log2 (N) / 2 con un resultado entero:

temp = (((uint32_t) N) * approx_log_base_2_N_times_256) / 512;

y todos los valores de 16 bits nunca estuvieron fuera por más del 2%

Consulte su curso de matemática básica, log n / log 2 . No importa si elige log o log10 en este caso, dividir por el log de la nueva base hace el truco.