1

How to find out the leftmost bit and rightmost bit of an number in one line of code ?

Well we can traverse an loop to find out the leftmost set bit by leftshift but how to do it in one line to make an another no. whose leftmost bit / rightmost bit is set ? Like y = x & ~(x-1) will find leftmost bit but I didn't get this how ?

Can someone give the code for that in C++ and explain ?

sagar saini
  • 107
  • 1
  • 7
  • 1) You didn't tag with a language; there are many languages with non-semantic line breaks, so _any_ program can be trivially a one-liner. 2) Why do you need this? is it a golf (a puzzle challenge to write code as short as possible), or would it be some other requirement? Does it need to be fast, or just not have line breaks? 3) Did you try anything yet? Have you researched it? – Amadan May 29 '19 at 11:01
  • What do you mean by *find* the left/right most bit? Return a value with only this bit set? Or return the index of this bit? – Alain Merigot May 29 '19 at 11:02
  • 4) Some programming languages have built-ins or library functions to do what you are looking for. For example, in Ruby, `x.bit_length - 1` will give you the index of the highest set bit. 5) It is also fairly trivial to do this by converting a number to the binary representation (which many languages support natively), then use string functions like `index`, `rindex` and `len` to find the ones (though it is not the most performant way). – Amadan May 29 '19 at 11:08

1 Answers1

4

For the rightmost bit, there is a well-known trick.

x=x & -x

will clear all set bits in x, except the rightmost one. You will find many explanations why this works in SO (see for instance this answer)

To find its index, except by using builtins of programming languages, there is no way but doing a loop AFAIK. Note that this loop can be unrolled to have a one liner.

pos = (16*(x&0xffff0000)!=0) + (8*(x&0xff00ff00)!=0) + (4&(x&0xf0f0f0f0)!=0) + (2*(x&0x66666666)!=0)+(x&0xaaaaaaaa)!=0)

x is the result of the previous operation (ie only the rightmost bit is set) and it works by testing is this bit is in the upper half word in which case the position will be > 16, then an even byte, even nibble, and so on.

Another solution, is to use the mathematic operator log2

pos=(int)log2((double)x)

For the left most bit, AFAIK, there are no way to do that at the bit level, except through loops. But it is possible to use log2() to find the position of the leftmost bit.

Then, to return an int with only this bit set, one can use right shifts.

x = 1 << ((int) log2((double)x))

This will keep only the left most bit in x.

Beware to previously check if x in non null.

Alain Merigot
  • 10,667
  • 3
  • 18
  • 31
  • @Amadan he didn't say "only way". What are you talking about? Alain didn't use built-in functions for his response. So why are you raising that concern? – C.J. May 30 '19 at 15:22