2011-02-11 17 views

Respuesta

39

Una forma es utilizar AND bit a bit. Si un número $x tiene una potencia de dos (por ejemplo, 8 = 1000), no tendrá bits en común con su predecesor (7 = 0111). Por lo tanto se puede escribir:

($x & ($x - 1)) == 0 

Nota: Esto le dará un falso positivo por $ x == 0.

+1

¿Hay otro caso de borde en el valor mínimo para un int? – anon

+1

@anon: la expresión siempre y solo devuelve un valor distinto de cero si el valor inicial tiene varios bits establecidos. El valor mínimo para un int tiene un bit establecido, debido al uso del complemento de dos (en la mayoría de las plataformas), pero no es un poder de 2. Así que sí, creo que tienes razón. Obtienes (para el caso de 8 bits) 10000000 & 01111111 == 0, lo que sería decir la verdad si estos fueran valores sin signo (128 es una potencia de 2), pero no para los valores firmados (-128 no es un poder de 2). – Steve314

-2
Math.log(x)/Math.log(2) == Math.floor(Math.log(x)/Math.log(2)) 
+1

Esto parece una solución razonable en Java en el primer vistazo - ** ¡pero no es así! ** ¡Nunca compare los flotadores/dobles con el operador '=='! – SebastianH

8

Restar 1 del número, a continuación, y con el número original. Si el resultado es cero, fue un poder de dos.

if (((n-1) & n) == 0) { 
    // power of two! 
} 

(lo siento, mi PHP es oxidado ...)

+3

jaja no es PHP! las variables son muy ricas y ricas! – mauris

+0

Lástima que no es un error de sintaxis si dejas tus variables rotas. – dan04

3

Si es una potencia de 2? Bueno, una forma es convertir a binario, y verificar la presencia de sólo 1 ... 1:

$bin = decbin($number); 
if (preg_match('/^0*10*$/', $bin)) { 
    //Even Power Of 2 
} 
2

Para completar, si el número es un flotador, puede probar si es una potencia de dos por chacking si la mantisa es todo ceros:

<?php 
$number = 1.2379400392853803e27; 
$d = unpack("h*", pack("d", $number)); $d = reset($d); 
$isPowerOfTwo = substr($d, 0, 13) == "0000000000000"; 
var_dump($isPowerOfTwo); // bool(true) 

ejercicio para el lector: casos de esquina y máquinas big-endian.

0

En un equivalente binario de cualquier número decimal que tenga una potencia de dos, solo tendrá una ocurrencia de 1 en su equivalente binario.

<?php 
    $number = 4096; 
    $bin = decbin($number); 
    if ($number != 1 && substr_count($bin,1) == 1) { 
     echo "Yes"; 
    } else { 
     echo "No"; 
    } 
?> 
Cuestiones relacionadas