PHP equivalent javascript >>> shift right with zero fill bitwise operators?

后端 未结 8 1308
孤城傲影
孤城傲影 2021-01-13 19:43

May I know how can I do PHP >>> ? Such operators is not available in PHP, but is available in Javascript.

I just managed to discover a function as follow:

         


        
相关标签:
8条回答
  • 2021-01-13 20:17

    Not sure if this works for php, I've manage to get it to work with C#.

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

    I found that out by debugging into the code that uses >>> comparing it with C# version of the code I converted from javascript. While trying out with b = 0, and using a scientific calculator to see the different hex/dec result of >> and >>> produce by javascript. When a is negative, >>> actually makes aa as unsigned.

    Not sure if that works for all scenario, but for my case the >>> is for md5 hashing. Being able to produce similar output, I'm quite satisfied with the result.

    Hope that helps

    0 讨论(0)
  • 2021-01-13 20:18

    For both 32-bit (PHP_INT_SIZE == 4) and 64-bit integers (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;
    }
    
    0 讨论(0)
  • 2021-01-13 20:23

    This works for me

    function RRR($a, $b){
        return (int)((float)$a/pow(2,(int)$b));
    }
    
    0 讨论(0)
  • 2021-01-13 20:25
    /**
     * 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;
    }
    

    Enjoy it.

    0 讨论(0)
  • 2021-01-13 20:34

    I've researched a lot on this, collected more than 11 versions from StackOverflow and open-source projects, none of them worked. But finally, I found the solution.

    For more details, live demo, tests and examples check my question and answer:
    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 &= 0x7fffffff; 
            $a |= 0x40000000; 
            $a = ($a >> ($b - 1)); 
        } else { 
            $a = ($a >> $b); 
        }
    
        return $a; 
    }
    
    0 讨论(0)
  • 2021-01-13 20:35

    Your function doesn't work because when $b == 0, the expression

    $a >> -1
    

    will be evaluated, which returns 0.

    Assuming 32-bit machines, you can add a special case:

    if ($z & $a) {
      if ($b == 0)
        return $a + 0x100000000;
      else {
        ...
    
    0 讨论(0)
提交回复
热议问题