PHP equivalent javascript >>> shift right with zer

2019-02-18 03:08发布

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:

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

but unfortunately, it doesn't work perfectly.

EG: -1149025787 >>> 0 Javascript returns 3145941509 PHP zeroFill() return 0

8条回答
萌系小妹纸
2楼-- · 2019-02-18 03:50

Twice as fast for negative numbers as using the decimal-binary conversions

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)); 
查看更多
放荡不羁爱自由
3楼-- · 2019-02-18 03:52

I studied around the webs and come out with my own zerofill function, base on the explanation given. This method works for my program.

Have a look:

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;
}
查看更多
Rolldiameter
4楼-- · 2019-02-18 03:52

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

查看更多
冷血范
5楼-- · 2019-02-18 03:55
/**
 * 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.

查看更多
Explosion°爆炸
6楼-- · 2019-02-18 04:02

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 {
    ...
查看更多
乱世女痞
7楼-- · 2019-02-18 04:06

This works for me

function RRR($a, $b){
    return (int)((float)$a/pow(2,(int)$b));
}
查看更多
登录 后发表回答