Bulkin
Bulkin

Reputation: 1040

How to set bits in byte without loop

I am really confused, but cannot to do simple task as it seems:

I simply need to set number of bits in byte.

For example:

I need 5 bits set. So I need 0xb00011111.

Is it possible to do this without loop?

Also I'd not like to write lot of #defines too.

Upvotes: 4

Views: 2044

Answers (3)

Achal
Achal

Reputation: 11921

Is it possible to do this without loop?

yes, it's possible to set n bits in given number without loop but not random bits, you can set n consecutive bits.

To set a single bit at given position

   num = num | 1 << pos ;

For setting 5 consecutive bits in given no you can use below logic

num = num | 31 << pos;

Here

31 ==> 1x2^0 + 1x2^1 + .. => 31 is the sum of 5 ones(1 1111)

Upvotes: 0

unwind
unwind

Reputation: 399733

For any integer n less than the number of bits in the word, the mask you need is:

const unsigned int mask = (1u << n) - 1;

No loop required.

A simple function using this:

unsigned int set_lsbs(unsigned int n)
{
  return (1u << n) - 1;
}

The ten first results are:

0: 0x0
1: 0x1
2: 0x3
3: 0x7
4: 0xf
5: 0x1f
6: 0x3f
7: 0x7f
8: 0xff
9: 0x1ff

Note: the syntax 0xb00011111 is not not a binary literal, that 'b' is simply interpreted as a hex digit.

Upvotes: 9

Clifford
Clifford

Reputation: 93466

Generation of a mask to set the least-significant 5 bits for any integer type can be done thus:

mask = ~((~0u) << 5) ;

This will create an integer value with the least significant 5 bits set to 1 and all higher-order bits regardless of integer type set to 0.

Specifically for the 8 bit type in question:

uint8_t mask = ~((~0u) << 5) ;

To explain how this works (ignoring intermediate integer types which are larger than 8 bits):

  • ~0u (one's compliment of zero) = 0x11111111
  • Then shifted by 5 = 0x11100000
  • Finally the one's complement of that = 0x00011111

Upvotes: 3

Related Questions