GMP Bit shift doesn't work on negative numbers

十年热恋 提交于 2019-12-11 01:57:20

问题


I found this function at php.net. It seems to work on positive numbers, but fails on negative ones:

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

How could I fix up the function to work with negatives?

Two ideas I have:

Maybe I could do something along the lines of

if (whatever) { $a >> $b} else{ gmp_shiftr($a, $b) }?

Or, maybe I could subtract something from the negative results depending on their value..?

I just want to get the value that >> would give, but also get it for >32bit numbers when I use GMP.


回答1:


Looking at the GMP documentation for the division routines, there's a function

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

that seems like it might be what you want: an arithmetic right shift that treats n as if it were represented in twos-complement, and (I think) shifts it b places to the right. Unfortunately, that level of the API doesn't seem to be exposed by PHP GMP.

I found a bit twiddling hack for doing sign extension when the number of bits in the representation is unknown:

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;

Since bitwise AND and XOR are supported by PHP GMP, you might be able to make this work...




回答2:


If you think about this mathematically it makes sense. gmp_shiftr is doing -1/256, which, when rounding towards zero (the gmp default) is 0.

The ">>" method works like it does because negative numbers are represented in sign-extended twos complement form.



来源:https://stackoverflow.com/questions/4800389/gmp-bit-shift-doesnt-work-on-negative-numbers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!