2010-04-15 10 views
4

Puis-je savoir comment puis-je faire PHP >>>? De tels opérateurs ne sont pas disponibles en PHP, mais sont disponibles en Javascript.PHP équivalent javascript >>> Maj droite avec des opérateurs de remplissage bit à zéro?

Je viens réussi à découvrir une fonction comme suit:

function zeroFill($a, $b) 
{ 
    $z = hexdec(80000000); 
     if ($z & $a) 
     { 
      $a = ($a>>1); 
      $a &= (~$z); 
      $a |= 0x40000000; 
      $a = ($a>>($b-1)); 
     } 
     else 
     { 
      $a = ($a>>$b); 
     } 
     return $a; 
} 

mais malheureusement, il ne fonctionne pas parfaitement.

EG: -1149025787 >>> 0 Javascript retourne 3145941509 PHP ZEROFILL() return 0

+2

pouvez-vous décrire ce qui se passe mal avec elle? – Cam

+1

J'imagine que vous avez vu: http://php.net/manual/en/language.operators.bitwise.php –

+0

@incrediment: Sur presque 100 résultat seulement 1 est incorrect: -1149025787 >>> 0 En javascript renvoie 3145941509 mais dans zeroFill() ci-dessus, il retourne juste 0. – neobie

Répondre

0

J'ai étudié autour des toiles et viens avec ma propre fonction ZEROFILL, la base sur l'explication donnée. Cette méthode fonctionne pour mon programme.

Jetez un oeil:

function zeroFill($a,$b) { 
    if ($a >= 0) { 
     return bindec(decbin($a>>$b)); //simply right shift for positive number 
    } 

    $bin = decbin($a>>$b); 

    $bin = substr($bin, $b); // zero fill on the left side 

    $o = bindec($bin); 
    return $o; 
} 
1

Votre fonction ne fonctionne pas parce que quand $b == 0, l'expression

$a >> -1 

sera évalué, qui retourne 0.

En supposant 32 bits machines, vous pouvez ajouter un cas spécial:

if ($z & $a) { 
    if ($b == 0) 
    return $a + 0x100000000; 
    else { 
    ... 
1

Je ne sais pas si cela fonctionne pour PHP, j'ai réussi à le faire fonctionner avec C#.

int a, b, result; 
//Instead of 
result = a >>> b; 
//I do 
result = (int)((uint)a >> b); 

Je trouve que par le débogage dans le code qui utilise >>> comparaison avec la version C# du code I converti de javascript. Tout en essayant avec b = 0, et en utilisant une calculatrice scientifique pour voir le résultat différent hex/déc de >> et >>> produire par javascript. Quand a est négatif, >>> fait réellement aa comme non signé.

Je ne sais pas si cela fonctionne pour tous les scénarios, mais pour mon cas, le >>> est pour le hachage MD5. Étant capable de produire une sortie similaire, je suis assez satisfait du résultat.

espoir qui aide

0

Cela fonctionne pour moi

function RRR($a, $b){ 
    return (int)((float)$a/pow(2,(int)$b)); 
} 
2

Deux fois plus rapide pour les nombres négatifs que l'utilisation des conversions décimales binaire

function zerofill($a,$b) { 
    if($a>=0) return $a>>$b; 
    if($b==0) return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1); 
    return ((~$a)>>$b)^(0x7fffffff>>($b-1)); 
1

Pour 32 bits (PHP_INT_SIZE = = 4) et des entiers 64 bits (PHP_INT_SIZE == 8):

function SHR 
($x, $c) 
{ 
    $x = intval ($x); // Because 13.5 >> 0 returns 13. We follow. 

    $nmaxBits = PHP_INT_SIZE * 8; 
    $c %= $nmaxBits; 

    if ($c) 
     return $x >> $c & ~ (-1 << $nmaxBits - $c); 
    else 
     return $x; 
} 
1

J'ai beaucoup étudié à ce sujet, recueilli plus de 11 versions de StackOverflow et des projets open-source, aucun d'entre eux travaillé. Mais finalement, j'ai trouvé la solution.

Pour plus de détails, démonstration en direct, des tests et des exemples vérifier ma question et de répondre:
Unsigned Right Shift/Zero-fill Right Shift in PHP (Java/JavaScript equivalent)

function unsignedRightShift($a, $b) { 
    if ($b >= 32 || $b < -32) { 
     $m = (int)($b/32); 
     $b = $b-($m*32); 
    } 

    if ($b < 0) { 
     $b = 32 + $b; 
    } 

    if ($b == 0) { 
     return (($a>>1)&0x7fffffff)*2+(($a>>$b)&1); 
    } 

    if ($a < 0) 
    { 
     $a = ($a >> 1); 
     $a &= 2147483647; 
     $a |= 0x40000000; 
     $a = ($a >> ($b - 1)); 
    } else { 
     $a = ($a >> $b); 
    } 

    return $a; 
}