3

I have an unsigned int that holds a series of bits, and a certain bit location.

Now I want to set all bits to 1 from that bit location 'downwards'. How can this be achieved simply without a loop?

Example:

unsigned int bitloc=2;
unsigned int bits=??;           //must become 0000 0111

unsigned int bitloc=4;
unsigned int bits=??;           //must become 0001 1111

Equivalent function that creates the result:

bits=0;
for (unsigned int i=0; i<=bitloc; i++)
    bits|=1<<i;
DoubleYou
  • 1,057
  • 11
  • 25

4 Answers4

2

How about?

unsigned int  Mask =   0xffffffff;
  bits = Mask >> (31 - bitloc);

as in your example bitloc is 2: Mask is a binary number of ones then we shift right it 29 time effectively adding 29 zeros from the left leaving only bit zero bit one and bit two as ones.

0xffffffff >> 29 = 0x00000007=000...0111

Hillel
  • 301
  • 1
  • 11
  • 1
    That's a different approach than the other answers, and it actually works for all `bitloc` including `bitloc==31`. And the same works when you want to use `bitloc` to let `bits` become `1110 0000` by simply using `~(Mask>>(32-bitloc))`. Clever! – DoubleYou Sep 03 '14 at 06:45
  • For 64-bit, use `~0ULL` instead of `0xFFFFFFFF` (the `~0` also works for `int` too). – Jonathan Leffler Sep 03 '14 at 06:50
  • @JonathanLeffler, simply using `-1` would work, wouldn't it: [link](http://stackoverflow.com/questions/809227/is-it-safe-to-use-1-to-set-all-bits-to-true)? – DoubleYou Sep 03 '14 at 06:56
  • 1
    @DoubleYou: In practice, yes, appropriately qualified. In theory, no; if the machine uses 1's complement or sign-magnitude binary numbers, `-1` won't work correctly (but `~0` will work even with those). – Jonathan Leffler Sep 03 '14 at 07:02
0

How about

bits |= (2 << bitloc) - 1;

Of course, this only works if bitloc <= 30.

user3386109
  • 34,287
  • 7
  • 49
  • 68
  • I think it should be `..(2ul << bitloc)..` – 0xF1 Sep 03 '14 at 05:51
  • So for `bitloc==31` create an if-statement containing `bits=-1`? – DoubleYou Sep 03 '14 at 05:54
  • @DoubleYou Yes, although `bits = ~0` might be preferred from a pedantic point of view. – user3386109 Sep 03 '14 at 05:58
  • @user3386109 I've taken `-1` from [here](http://stackoverflow.com/questions/809227/is-it-safe-to-use-1-to-set-all-bits-to-true) as `~0` can behave differently on different systems. – DoubleYou Sep 03 '14 at 06:27
  • @DoubleYou interesting, in that case you shouldn't need an `if` statement at all, since the expression will evaluate to -1 on a 32-bit machine when `bitloc` is 31. – user3386109 Sep 03 '14 at 06:47
0

I hope this should work,

bits |= ~((~0)<<(bitloc + 1))
Adarsh
  • 883
  • 7
  • 18
0

Here is the more generic solution for your question

Lets say you want to set "N" bits from a specific position "P" from M.S.B. towards LSB in a given value "X". Then the solution will be


X = X | ((~(~0 << N)) << ((P + 1) - N));

SACHIN DHIVARE
  • 115
  • 1
  • 1
  • 7