2

我在 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) }?

或者,也许我可以根据它们的价值从负面结果中减去一些东西..?

我只想获得 >> 会给出的值,但在我使用 GMP 时也获得 >32 位数字的值。

4

2 回答 2

1

查看除法例程的GMP文档,有一个功能

void mpz_tdiv_q_2exp (mpz_t q, mpz_t n, unsigned long int b)

这似乎可能是您想要的:算术右移,将其 n视为以二进制补码表示,并且(我认为)将其b右移。不幸的是,PHP GMP 似乎没有公开该级别的 API。

当表示中的位数未知时,我发现了一些用于进行符号扩展的小技巧:

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 ,也许可以完成这项工作......

于 2011-01-26T01:20:35.800 回答
0

如果您从数学上考虑这一点,那是有道理的。gmp_shiftr 正在执行 -1/256,当向零舍入时(gmp 默认值)为 0。

">>" 方法的工作原理与此类似,因为负数以符号扩展的二进制补码形式表示。

于 2011-01-26T01:09:46.267 回答