2011-03-07 3 views
1

http://www-graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallelL'équivalent PHP du code C de Bit Twiddling Hacks?

v = v - ((v >> 1) & (T)~(T)0/3);  // temp 
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);  // temp 
v = (v + (v >> 4)) & (T)~(T)0/255*15;      // temp 
c = (T)(v * ((T)~(T)0/255)) >> (sizeof(v) - 1) * CHAR_BIT; // count 

Ceci est le même problème en Python: Python equivalent of C code from Bit Twiddling Hacks?

Je dois utiliser ce code en PHP, indépendamment de la taille entier (le code ci-dessus fonctionne jusqu'à entiers de 128 bits, ce qui va fais bien pour moi). Voici ce que j'ai essayé:

function countSetBits($int) { 
     $mask = (1 << PHP_INT_SIZE*8) - 1; 
     $int = $int - (($int >> 1) & (int) $mask/3); 
     $int = ($int & ((int) $mask/15)*3) + (($int >> 2) & ((int) $mask/15)*3); 
     $int = ($int + ($int >> 4)) & ((int) $mask/255)*15; 
     return ($mask & $int * ((int) $mask/255)) >> ((int) PHP_INT_SIZE - 1) * 8; 
} 

La raison pour laquelle cela ne fonctionne pas - est que PHP ne semble pas supporter des entiers non signés 64 bits ((sur une machine 64 bits avec PHP 64 bits Debian Squeeze) how to have 64 bit integer on PHP?). Je crains de devoir utiliser une bibliothèque mathématique de précision arbitraire. Ou y a-t-il un autre moyen?

Répondre

2

Pour l'instant, voici ce que je:

function countSetBits($int) { 
      return substr_count(base_convert($int, 10, 2), '1'); 
    } 
+0

Ceci est probablement plus efficace de toute façon. Dans un langage interprété, il est préférable d'appeler deux fonctions natives plutôt que d'utiliser deux douzaines d'opérateurs. Essayez également ['decbin'] (http://php.net/manual/fr/function.decbin.php). – aaz

1

Essayez d'utiliser les éléments suivants dans votre script php avant les opérations 64 bits:

ini_set('precision', 20);