我花了最后几个小时尝试将其移植到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;
}
答案 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;
}