我在php.net上找到了这个功能。它似乎对正数有效,但对负数无效:
function gmp_shiftr($x,$n) { // shift right
return(gmp_div($x,gmp_pow(2,$n)));
}
echo -1 >> 8; //returns -1, presumably correctly
echo "<br />";
echo gmp_strval(gmp_shiftr(-1,8)); //returns 0, presumably incorrectly
如何修复功能以处理否定数据?
我有两个想法:
也许我可以按照
的方式做点什么if (whatever) { $a >> $b} else{ gmp_shiftr($a, $b) }?
或者,也许我可以根据它们的价值从负面结果中减去一些东西。?
我只想获得&gt;&gt;的值当我使用GMP时,它会给出&gt; 32位数字。
答案 0 :(得分:1)
查看GMP documentation for the division routines,有一个功能
void mpz_tdiv_q_2exp (mpz_t q, mpz_t n, unsigned long int b)
似乎它可能是你想要的:一个对待的算术右移
n
好像它是以二进制补码表示的,并且(我认为)将其移位b
个位置
在右边。不幸的是,PHP的这个级别似乎没有被PHP GMP公开。
我找到了一个bit twiddling hack来进行符号扩展时的位数 在表示中是未知的:
unsigned b; // number of bits representing the number in x
int x; // sign extend this b-bit number to r
int r; // resulting sign-extended number
int const m = 1U << (b - 1); // mask can be pre-computed if b is fixed
x = x & ((1U << b) - 1); // (Skip this if bits in x above position b are already zero.)
r = (x ^ m) - m;
由于PHP GMP支持按位AND和XOR ,因此您可以制作 这项工作......
答案 1 :(得分:0)
如果你从数学角度思考它,那就有道理了。 gmp_shiftr正在执行-1/256,当向零舍入(gmp默认值)为0时。
“&gt;&gt;”方法的工作方式与此相同,因为负数以符号扩展的二进制补码形式表示。