0

Is there a method to get the position of the most significant bit, that is floor(log(x)/log(2)) + 1?

Currently I'm running the following abomination:

bitcount(a)={
   my(l2, ap, l2ap);
   if(a == 0,
      return(0);
   ); 
   \\ TODO: set upper limit according to current precision
   if(a < 2^32,
      l2 = floor(log(a)/log(2));
      return(l2 + 1);
   );
   \\ Argument reduction
   l2 = floor(log(a)/log(2)) - 2;
   ap = a >> l2;
   \\ Get the fine details.
   l2ap = floor(log(ap)/log(2));
   ap = l2 + l2ap;
   return(ap + 1);
}

This was necessary because I'm working with larger numbers and the precision necessary to make floor(log(2^(2^31) - 1)/log(2)) + 1 to print the correct result 2147483647 instead of the wrong 2147483648 is prohibitively large.

Is there really no build-in function in PARI/GP to get the position of the MSB?

deamentiaemundi
  • 5,502
  • 2
  • 12
  • 20
  • Is the `binary` function a solution? For some input integer `n`, the 1-based position of MSB can be obtained just as `#binary(n)`. E.g., `#binary(2^131) = 132`. – Piotr Semenov Nov 26 '19 at 17:02
  • @PiotrSemenov `binary()` returns a vector, needs a large amount of memory on top of the one gigabyte for `2^(2^31)` and just counts the entries in the vector. Works well for small numbers but not for the larger ones I use. – deamentiaemundi Nov 26 '19 at 17:19

1 Answers1

1

To get the msb, just use 'logint(n, 2)'. If you want lsb use 'valuation(n, 2)'.

There is also a built in function 'hammingweight' that will give you the number of 1 bits.

Andrew
  • 873
  • 4
  • 10