6171

GMP Bit shift doesn't work on negative numbers

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.

Answer1:

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...

Answer2:

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.

Recommend

  • Can I build gcc for ARM with an X64 one?
  • Calculations with integers with more than 16 digits
  • What is the efficient way to find some pattern in a big text?
  • get count of all positive values from a the last 150 rows at each row - pandas
  • Add C library to docker
  • Use Google font or host font myself [closed]
  • Requiring sudo to run ghci on OSx
  • Tkinter: Determine Widget Position relative to Root Window
  • Timer once a minute on the minute
  • Finding the number of elements less than or equal to k in a multiset
  • Why do GeoJSON features appear like a negative photo of the features themselves?
  • How to use the resource module to measure the running time of a function?
  • Is playing sound in Javascript performance heavy?
  • What and where is mdimport
  • Does it make sense to call System.gc() and Thread.sleep() when working on Bitmaps?
  • jQuery ready not fired after rails link_to is clicked
  • Allowing both email and username for authentication
  • Yii2: Config params vs. const/define
  • Algorithm for a smudge tool?
  • R - Combining Columns to String Based on Logical Match
  • Get one-time binding to work for ng-if
  • Linq Objects Group By & Sum
  • Insert into database using onclick function
  • Read text file and split every line in MSBuild
  • Optimizing database types to compact database (SQLite)
  • Get object from AWS S3 as a stream
  • Java applet as stand-alone Windows application?
  • Knitr HTML Loop - Some HTML output, some R output
  • Can a Chrome extension content script make an jQuery AJAX request for an html file that is itself a
  • How do you troubleshoot character encoding problems?
  • Jquery - Jquery Wysiwyg return html as a string
  • Return words with double consecutive letters
  • how to add data labels for bar graph in matlab
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • Buffer size for converting unsigned long to string
  • SQL merge duplicate rows and join values that are different
  • How to get Windows thread pool to call class member function?
  • Django query for large number of relationships
  • reshape alternating columns in less time and using less memory
  • Reading document lines to the user (python)