有人可以把它移植到C?

时间:2010-05-28 19:54:56

标签: php c

我花了最后几个小时尝试将其移植到C,但没有成功。有人可以帮忙吗?

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

2 个答案:

答案 0 :(得分:4)

怎么样

unsigned int zerofill(unsigned int a, int b) {
    return a >> b;
}

或者,

int zerofill(int a, int b) {
    return ((unsigned int)a) >> b;
}

在C中,右移位运算符如果其左操作数是有符号的,则用作算术移位;如果是无符号,则用作逻辑移位。似乎原始的PHP代码只需要一个有符号的移位就可以获得一个无符号的移位。

第6.5.7节中的C99标准说:

  

E1 >> E2的结果是E1右移E2位位置。   如果E1具有无符号类型,或者E1具有签名类型且具有   非负值,结果的值是积分   E1 / 2^E2的商的一部分。如果E1具有签名类型   和负值,结果值是   实现定义的。

这清楚地表明,为了使零位移入,操作数必须是无符号的,或者是有符号和正的。唯一的问题是操作数签名时的行为和结果是实现定义的否定。在实践中,我遇到的每个实现都通过符号扩展来处理这种情况,这样当整数值存储为二进制补码时,结果仍然可以用2的幂除法。

我手头没有参考资料,但是C89实际上说了同样的事情,并且在C标准之前建立的惯例也与此解释一致。

答案 1 :(得分:1)

未经测试,但是,大部分代码都是相同的。

int zerofill(int a, int b) {
    int z = 0x80000000;
    if (z & a) {
        a = a >> 1;
        a &= ~z;
        a |= 0x40000000;
        a = a >> (b - 1);
    } else {
        a = a >> b;
    }
    return a;
}