una sirve raiz que potencia para numero metodo exponente elevar cubica codigo calcular java performance

java - sirve - Forma rápida de encontrar exponente de la potencia superior más cercana de 2.



potencia java codigo (9)

Si tengo un número a , quiero el valor de x en b = 2 ^ x , donde b es la siguiente potencia de 2 mayor que a .

En caso de que se haya perdido la etiqueta, esta es Java, y a es un int. Estoy buscando la manera más rápida de hacer esto. Por lo tanto, mi solución es utilizar twiddling de bits para obtener b , luego hacer (int) (log ( b ) / log (2)), pero siento que debe haber un método más rápido que no implique dividir dos números de punto.


¿Qué hay de a == 0 ? 0 : 32 - Integer.numberOfLeadingZeros(a - 1) a == 0 ? 0 : 32 - Integer.numberOfLeadingZeros(a - 1) ? Eso evita por completo el punto flotante. Si sabe que a nunca es 0, puede omitir la primera parte.


¿Qué tal dividir y conquistar? Como en:

b = 0; if (a >= 65536){a /= 65536; b += 16;} if (a >= 256){a /= 256; b += 8;} if (a >= 16){a /= 16; b += 4;} if (a >= 4){a /= 4; b += 2;} if (a >= 2){a /= 2; b += 1;}

Suponiendo que a no está firmado, las divisiones deben ser simplemente cambios de bits.

Un IF-tree binario con 32 hojas debería ser aún más rápido, obteniendo la respuesta en 5 comparaciones. Algo como:

if (a >= (1<<0x10)){ if (a >= (1<<0x18)){ if (a >= (1<<0x1C)){ if (a >= (1<<0x1E)){ if (a >= (1<<0x1F)){ b = 0x1F; } else { b = 0x1E; } } else { if (a >= (1<<0x1D)){ b = 0x1D; } else { b = 0x1C; } } etc. etc.


Aquí está mi código para el mismo. ¿Será esto más rápido?

int a,b,x,y; Scanner inp = new Scanner(System.in); a = inp.nextInt(); y = (int) (Math.log(a)/Math.log(2)); x = y +1; System.out.println(x);


Java proporciona una función que se redondea a la potencia más cercana de 2. Por lo tanto, a!=Integer.highestOneBit(a)?2*Integer.highestOneBit(a):a es una solución ligeramente más bonita, suponiendo que a es positiva.

El almacenamiento de Integer.highestOneBit(a) en una variable puede mejorar aún más el rendimiento y la legibilidad.


No necesariamente más rápido, sino un trazador de líneas:

int nextPowerOf2(int num) { return num == 1 ? 1 : Integer.highestOneBit(num - 1) * 2; }


Para agregar a la respuesta de Jeremiah Willcock, si desea el valor del poder de 2 en sí, entonces querrá:

(int) Math.pow(2, (a == 0) ? 0 : 32 - Integer.numberOfLeadingZeros(numWorkers));


Si alguien está buscando un código de "twiddling de bits" que Andy menciona, podría ser algo como esto: (si la gente tiene mejores maneras, ¡debería compartir!)

public static int nextPowerOf2(final int a) { int b = 1; while (b < a) { b = b << 1; } return b; }


Si necesita una respuesta que funcione para enteros o punto flotante, ambos deberían funcionar:

Math.floor(Math.log(a) * 1.4426950408889634073599246810019) + 1 que Math.floor(Math.log(a) * 1.4426950408889634073599246810019) + 1 sería su mejor apuesta si no quiere hacer un poco de twiddling.

Si desea dividir en bits, puede usar Double.doubleToLongBits(a) y luego simplemente extraer el exponente. Estoy pensando ((Double.doubleRawToLongBits(a) >>> 52) & 0x7ff) - 1022 debería hacer el truco.


solo haz lo siguiente:

extraiga el bit más alto utilizando este método (modificado desde hdcode):

int msb(int x) { if (pow2(x)) return x; x = x | (x >> 1); x = x | (x >> 2); x = x | (x >> 4); x = x | (x >> 8); x = x | (x >> 16); x = x | (x >> 24); return x - (x >> 1); } int pow2(int n) { return (n) & (n-1) == 0; }

combinando ambas funciones en esta función para obtener un número ''b'', que es la siguiente potencia de 2 de un número dado ''a'':

int log2(int x) { int pow = 0; if(x >= (1 << 16)) { x >>= 16; pow += 16;} if(x >= (1 << 8 )) { x >>= 8; pow += 8;} if(x >= (1 << 4 )) { x >>= 4; pow += 4;} if(x >= (1 << 2 )) { x >>= 2; pow += 2;} if(x >= (1 << 1 )) { x >>= 1; pow += 1;} return pow; }

Saludos cordiales, Dave