I want to calculate 2n-1 for a 64bit integer value.
What I currently do is this
for(i=0; i<n; i++) r|=1<<i;
and I wonder if there is more elegant way to do it.
The line is in an inner loop, so I need it to be fast.
I thought of
r=(1ULL<<n)-1;
but it doesn’t work for n=64, because << is only defined
for values of n up to 63.
EDIT:
Thanks for all your answers and comments.
Here is a little table with the solutions that I tried and liked best.
Second column is time in seconds of my (completely unscientific) benchmark.
r=N2MINUSONE_LUT[n]; 3.9 lookup table = fastest, answer by aviraldg r =n?~0ull>>(64 - n):0ull; 5.9 fastest without LUT, comment by Christoph r=(1ULL<<n)-1; 5.9 Obvious but WRONG! r =(n==64)?-1:(1ULL<<n)-1; 7.0 Short, clear and quite fast, answer by Gabe r=((1ULL<<(n/2))<<((n+1)/2))-1; 8.2 Nice, w/o spec. case, answer by drawnonward r=(1ULL<<n-1)+((1ULL<<n-1)-1); 9.2 Nice, w/o spec. case, answer by David Lively r=pow(2, n)-1; 99.0 Just for comparison for(i=0; i<n; i++) r|=1<<i; 123.7 My original solution = lame
I accepted
r =n?~0ull>>(64 - n):0ull;
as answer because it’s in my opinion the most elegant solution.
It was Christoph who came up with it at first, but unfortunately he only posted it in a
comment. Jens Gustedt added a really nice rationale, so I accept his answer instead. Because I liked Aviral Dasgupta’s lookup table solution it got 50 reputation points via a bounty.
I like aviraldg answer best.
Just to get rid of the `ULL’ stuff etc in C99 I would do
static inline uint64_t n2minusone(unsigned n) { return n ? (~(uint64_t)0) >> (64u - n) : 0; }To see that this is valid
64 one bits
shift, so everything is filled with zeros from the left
yes you have to do at least one conditional to be sure of your result
prefer) makes this type safe; an
unsigned long longmaywell be an 128 bit wide value in the future
static inlinefunction should be seamlesslyinlined in the caller without any overhead