1.Setting a bit
DescriptionSetting the x-th bit of a number means changing the x-th bit value to 1.
Example
Considering a number a = 36, we shall set its 6th bit.
Bits | 7th | 6th | 5th | 4th | 3rd | 2nd | 1st | 0th | |
a | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 36 |
a set 6 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 100 |
#include<stdio.h> #include<stdint.h> int main(void) { uint8_t a=36; uint8_t b=6; a |= (1<<b); printf("a set b : %u",a); return 0; } /*Output a set b : 100 */
2.Clearing a bit
DescriptionClearing the x-th bit of a number means changing the x-th bit value to 0.
Example
Bits | 7th | 6th | 5th | 4th | 3rd | 2nd | 1st | 0th | |
a | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 36 |
a clear 5 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 4 |
#include<stdio.h> #include<stdint.h> int main(void) { uint8_t a=100; uint8_t b=6; a &= ~(1<<b); printf("a clr b : %u",a); return 0; } /*Output a clr b : 36 */
3.Checking a bit
DescriptionChecking the x-th bit of a number means verifying the value of x-th bit (which can be 0 or 1).
Example:
a = 36 = 0010 0100
After checking the 5th bit, the value which is returned should be 1.
Syntax
#include<stdio.h> #include<stdint.h> int main(void) { uint8_t a=100; uint8_t b=6; uint8_t checkResult = a & (1<<b); printf("a chk b : %u",checkResult); return 0; } /*Output a chk b : 64 */
4.Toggling a bit
Toggling the x-th bit of a number means changing its current value to its complementary value (if the bit is 1, it will be 0 and if the bit is 0 it will be 1).Example:
Bits | 7th | 6th | 5th | 4th | 3rd | 2nd | 1st | 0th | |
a | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 36 |
a toggle 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 37 |
a toggle 5 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 4 |
Syntax
#include<stdio.h> #include<stdint.h> int main(void) { uint8_t a=36; uint8_t b=5; a ^= (1<<b); printf("a tgl b : %u",a); return 0; } /*Output a tgl b : 4 */
5.Copying bits from a number to another
DescriptionCopying bits means that you modify certain bits of a number according to the same certain bits of another number. Those "certain bits" are called a mask.
Example:
Let us consider two numbers a and b where a = 36 and b = 6. We will want concatenate the first 4 bits of a and the last 4 bits of b. In order to do this we shall define a mask who needs to have the bits we want to get from a set to 1 and the bits we want to get from b set to 0. So mask will be equal to 240.
Bits | 7th | 6th | 5th | 4th | 3rd | 2nd | 1st | 0th | |
a | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 36 |
b | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 6 |
mask | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 240 |
~mask | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 15 |
In order to concatenate a and b, we will need to clear the bits we do not want to be in the final number by using the AND operator. Then we shall concatenate the results using the OR operator.
a' = a AND mask
b' = b AND (~mask)
res = a' OR b'
Bits | 7th | 6th | 5th | 4th | 3rd | 2nd | 1st | 0th | |
a | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 36 |
b | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 6 |
mask | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 240 |
~mask | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 15 |
a & (mask) | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 32 |
b & (~mask) | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 6 |
a' | b' | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 38 |
Syntax
#include<stdio.h> #include<stdint.h> int main(void) { uint8_t a=36; uint8_t b=6; uint8_t mask = 240; a = (a&mask)|( b&(~mask) ); printf("a cpy b : %u",a); return 0; } /*Output a cpy b : 38 */Since these operations are used often (especially on embedded systems), here are some macros for them:
#define BitSet(a,b) ( (a) |= ( 1<<(b) ) ) #define BitClear(a,b) ( (a) &= ~( 1<<(b) ) ) #define BitCheck(a,b) ( (a) & ( 1<<(b) ) ) #define BitToggle(a,b) ( (a) ^= ( 1<<(b) ) ) #define BitCopy(a,mask,b) ( (a) = ( (a) & (mask) )|( (b) & (~(mask) ) )Question: How often do you use in projects these bitwise operations?
References:
http://stackoverflow.com/questions/47981/how-do-you-set-clear-and-toggle-a-single-bit-in-c
No comments:
Post a Comment
Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!