Set m-bit to n-bit

I have a 32-bit and without using for a loop, I want to set the m bit bit to n .

For example:

m bit may be 2nd or 5th or 9th or 10th .
bit n may be bit 22nd or 27 or 11th .

I guess (m <n).

Please help me. thanks

-one
c bit-manipulation
source share
1 answer

Although the question was closed, but since I was not sure of my old answer. I updated with verified code. Hope it will be useful for someone in the future.

Suppose the bits are numbered from LSB to MSB:

 BIT NUMBER 31 0 ▼ ▼ number bits 0000 0000 0000 0000 0000 0000 0001 0101 ^ ^ ▲ MSB | | LSM | | n=27 m=17 LSB - Least Significant Bit (numbered 0) MSB - Most Significant Bit (numbered 31) 

The figure above shows how the bits are numbered from LSB to MSB. Note the relative positions of n and m , where n > m .


Set all bits One from n to m


To set 1 all bits from position m to n (where n > m ) to a 32-bit number. You need a 32-bit mask in which all bits 1 from n to m and the remaining bits are 0 .

For example, to set all the bits from m=17 to n=27 , we need a mask, for example:

 BIT NUMBER 31 n=27 m=17 0 ▼ ▼ ▼ ▼ mask = 0000 1111 1111 1110 0000 0000 0000 0000 

And if we have a 32-bit number, a bitwise OR ( | ) with this number, we can set 1 all the bits from m to n . And other bits will not be changed.

remember OR works like:

 x | 1 = 1 , and x | 0 = x 

where x value can be 1 or 0 any.

Thus:

  num32bit = num32bit | mask; 

we can set n to m bit 1 , and the remaining bits will not be changed. Example, Suppose num32bit = 0011 1001 1000 0000 0111 1001 0010 1101

then:

 0011 1001 1000 0000 0111 1001 0010 1101 <--- num32bit 0000 1111 1111 1110 0000 0000 0000 0000 <--- mask ---------------------------------------- ---------------Bitwise OR operation 0011 1111 1111 1110 0111 1001 0010 1101 <--- new number ---- ▲ ▲ ------------------- |-----------| this bits are from `num32bit` all bits are 1 here "This is what I means by": num32bit = num32bit | mask; 

How to make a mask?

Make a mask in which all bits 1 from n to m and the others are 0 . we need three steps:

  • Create mask_n : all bits on the right side of n=27 are equal

      BIT NUMBER 31 n=27 0 ▼ ▼ ▼ mask_27= 0000 1111 1111 1111 1111 1111 1111 1111 

    In programming, this can be created using Right-Shift → 4 times.

    And, how 4 came?

      4 = 32 - n - 1 ==> 31 - 27 ==> 4 

    Also note that in the complement ( ~ ) of form 0 all bits are equal to one. and we need an unsigned right shift in C.
    Link to find out the difference between a signed and an unsigned right shift

  • Create mask_m . All bits on the left side of m=17 are equal to one.

      BIT NUMBER 31 m=17 0 ▼ ▼ ▼ mask_17 1111 1111 1111 1110 0000 0000 0000 0000 
  • Create mask : Bitwise And higher: mask = mask_n & mask_m :

      mask = 0000 1111 1111 1110 0000 0000 0000 0000 ▲ ▲ BIT NUMBER 27 17 

And below, my getMask(n, m) function returns an unsigned number that looks like a mask in step 3.

 #define BYTE 8 typedef char byte; // Bit_sizeof(char) == BYTE unsigned getMask(unsigned n, unsigned m){ byte noOfBits = sizeof(unsigned) * BYTE; unsigned mask_n = ((unsigned)~0u) >> (noOfBits - n - 1), mask_m = (~0u) << (noOfBits - m), mask = mask_n & mask_m; // bitwise & of 2 sub masks return mask; } 

To test my getMask (), I also wrote the main () code that uses the binary () function, the binary () function prints the given number in binary formate.

 void binary(unsigned); int main(){ unsigned num32bit = 964720941u; unsigned mask = 0u; unsigned rsult32bit; int i = 51; mask = getMask(27, 17); rsult32bit = num32bit | mask; //set n to m bits 1 printf("\nSize of int is = %ld bits, and " "Size of unsigned = %ld eg\n", sizeof(int) * BYTE, sizeof(unsigned) * BYTE); printf("dec= %-4u, bin= ", 21); binary(21); printf("\n\n%s %d\n\t ", "num32bit =", num32bit); binary(num32bit); printf("mask\t "); binary(mask); while(i--) printf("-"); printf("\n\t "); binary(rsult32bit); printf("\n"); return EXIT_SUCCESS; } void binary(unsigned dec){ int i = 0, left = sizeof(unsigned) * BYTE - 1; for(i = 0; left >= 0; left--, i++){ printf("%d", !!(dec & ( 1 << left ))); if(!((i + 1) % 4)) printf(" "); } printf("\n"); } 

This test code works like (the output is the same as I explained in the above example):

 Output of code: ----------------- $ gcc bc :~$ ./a.out Size of int is = 32 bits, and Size of unsigned = 32 eg dec= 21 , bin= 0000 0000 0000 0000 0000 0000 0001 0101 num32bit = 964720941 0011 1001 1000 0000 0111 1001 0010 1101 mask 0000 1111 1111 1110 0000 0000 0000 0000 --------------------------------------------------- 0011 1111 1111 1110 0111 1001 0010 1101 :~$ 

Additionally, you can write the getMask () function in shorter form in two operations:

 unsigned getMask(unsigned n, unsigned m){ byte noOfBits = sizeof(unsigned) * BYTE; return ((unsigned)~0u >> (noOfBits - n - 1)) & (~0u << (noOfBits -m)); } 

Note: I removed the redundant brackets to clear the code. Although you never need to remember the priority of the operators, since you can overwrite the priority using () . But a good programmer always referees to the priority table to write neat code.

And Macro () is best suited, as shown below:

 #define BYTE 8 #define _NO_OF_BITS sizeof(unsigned) * BYTE #define MASK(n, m) (((unsigned)~0u >> (_NO_OF_BITS - n - 1)) & \ (~0u << (_NO_OF_BITS - m))) 

And call:

 rsult32bit = num32bit | MASK(27, 17); 

To set all zero bits from n to m


To set all bits from n to m = 0 and reset, you do not need the ( ~ ) mask padding.

 mask 0000 1111 1111 1111 1000 0000 0000 0000 ~mask 1111 0000 0000 0000 0111 1111 1111 1111 <-- complement 

Also required operator | to set zero & .

Remember And it works like:

 x & 0 = 0 , and x & 0 = 0 

where x value can be 1 or 0.

Since we already have the bitwise complement operator ~ and the & operator. We just need to do it.
[SOLUTION] :

 rsult32bit = num32bit & ~MASK(27, 17); 

And it will work as:

 num32bit = 964720941 0011 1001 1000 0000 0111 1001 0010 1101 mask 1111 0000 0000 0000 0111 1111 1111 1111 --------------------------------------------------- 0011 0000 0000 0000 0111 1001 0010 1101 
+8
source share

All Articles