PHP équivalent javascript >>> Shift à droite avec des opérateurs de bit de remplissage zéro?

StackOverflow https://stackoverflow.com/questions/2642026

Question

Puis-je savoir comment puis-je faire PHP >>>? Ces opérateurs ne sont pas disponibles en PHP, mais sont disponibles en JavaScript.

J'ai juste 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, cela ne fonctionne pas parfaitement.

Par exemple: -1149025787 >>> 0 JavaScript Retour 3145941509 PHP Zerofill () Retour 0

Était-ce utile?

La solution 4

J'ai étudié autour des toiles et je suis sorti avec ma propre fonction Zerofill, à la base de l'explication donnée. Cette méthode fonctionne pour mon programme.

Regarde:

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

Autres conseils

/**
 * The >>> javascript operator in php x86_64
 * Usage: -1149025787 >>> 0 ---> rrr(-1149025787, 0) === 3145941509
 * @param int $v
 * @param int $n
 * @return int
 */
function rrr($v, $n)
{
    return ($v & 0xFFFFFFFF) >> ($n & 0x1F);
}

/**
 * The >> javascript operator in php x86_64
 * @param int $v
 * @param int $n
 * @return int
 */
function rr($v, $n)
{
    return ($v & 0x80000000 ? $v | 0xFFFFFFFF00000000 : $v & 0xFFFFFFFF) >> ($n & 0x1F);
}


/**
 * The << javascript operator in php x86_64
 * @param int $v
 * @param int $n
 * @return int
 */
function ll($v, $n)
{
    return ($t = ($v & 0xFFFFFFFF) << ($n & 0x1F)) & 0x80000000 ? $t | 0xFFFFFFFF00000000 : $t & 0xFFFFFFFF;
}

Profitez-en.

Deux fois plus vite pour les nombres négatifs que l'utilisation des conversions décimales-binaires

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

J'ai beaucoup recherché à ce sujet, collecté plus de 11 versions dans des projets Stackoverflow et open source, aucun d'entre eux n'a fonctionné. Mais finalement, j'ai trouvé la solution.

Pour plus de détails, la démo en direct, les tests et les exemples consultent ma question et la réponse:
Shift à droite non signé / décalage à droite zéro en php (équivalent Java / JavaScript)

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 &= 0x7fffffff; 
        $a |= 0x40000000; 
        $a = ($a >> ($b - 1)); 
    } else { 
        $a = ($a >> $b); 
    }

    return $a; 
}

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

$a >> -1

sera évalué, ce qui renvoie 0.

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

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

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 l'ai découvert en débogues dans le code qui utilise >>> La comparaison avec la version C # du code que j'ai converti à partir de JavaScript. Tout en essayant avec b = 0, et en utilisant une calculatrice scientifique pour voir les différents résultats hexadérandus / DEC de >> et >>> Produit par JavaScript. Lorsque a est négatif, >>> fait en fait AA aussi non signé.

Je ne sais pas si cela fonctionne pour tout scénario, mais pour mon cas >>> est pour le hachage MD5. Pouvoir produire une sortie similaire, je suis assez satisfait du résultat.

J'espère que cela pourra aider

Pour les entiers 32 bits (php_int_size == 4) et 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;
}

Cela fonctionne pour moi

function RRR($a, $b){
    return (int)((float)$a/pow(2,(int)$b));
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top