Related
How do I set, clear, and toggle a bit?
Setting a bit
Use the bitwise OR operator (|) to set a bit.
number |= 1UL << n;
That will set the nth bit of number. n should be zero, if you want to set the 1st bit and so on upto n-1, if you want to set the nth bit.
Use 1ULL if number is wider than unsigned long; promotion of 1UL << n doesn't happen until after evaluating 1UL << n where it's undefined behaviour to shift by more than the width of a long. The same applies to all the rest of the examples.
Clearing a bit
Use the bitwise AND operator (&) to clear a bit.
number &= ~(1UL << n);
That will clear the nth bit of number. You must invert the bit string with the bitwise NOT operator (~), then AND it.
Toggling a bit
The XOR operator (^) can be used to toggle a bit.
number ^= 1UL << n;
That will toggle the nth bit of number.
Checking a bit
You didn't ask for this, but I might as well add it.
To check a bit, shift the number n to the right, then bitwise AND it:
bit = (number >> n) & 1U;
That will put the value of the nth bit of number into the variable bit.
Changing the nth bit to x
Setting the nth bit to either 1 or 0 can be achieved with the following on a 2's complement C++ implementation:
number ^= (-x ^ number) & (1UL << n);
Bit n will be set if x is 1, and cleared if x is 0. If x has some other value, you get garbage. x = !!x will booleanize it to 0 or 1.
To make this independent of 2's complement negation behaviour (where -1 has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
or
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
It's generally a good idea to use unsigned types for portable bit manipulation.
or
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n)) will clear the nth bit and (x << n) will set the nth bit to x.
It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down) or some sort of encapsulation.
Using the Standard C++ Library: std::bitset<N>.
Or the Boost version: boost::dynamic_bitset.
There is no need to roll your own:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x;
x[1] = 1;
x[2] = 0;
// Note x[0-4] valid
std::cout << x << std::endl;
}
[Alpha:] > ./a.out
00010
The Boost version allows a runtime sized bitset compared with a standard library compile-time sized bitset.
The other option is to use bit fields:
struct bits {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
};
struct bits mybits;
defines a 3-bit field (actually, it's three 1-bit felds). Bit operations now become a bit (haha) simpler:
To set or clear a bit:
mybits.b = 1;
mybits.c = 0;
To toggle a bit:
mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1; /* all work */
Checking a bit:
if (mybits.c) //if mybits.c is non zero the next line below will execute
This only works with fixed-size bit fields. Otherwise you have to resort to the bit-twiddling techniques described in previous posts.
I use macros defined in a header file to handle bit set and clear:
/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1
#define BITMASK_SET(x, mask) ((x) |= (mask))
#define BITMASK_CLEAR(x, mask) ((x) &= (~(mask)))
#define BITMASK_FLIP(x, mask) ((x) ^= (mask))
#define BITMASK_CHECK_ALL(x, mask) (!(~(x) & (mask)))
#define BITMASK_CHECK_ANY(x, mask) ((x) & (mask))
It is sometimes worth using an enum to name the bits:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Then use the names later on. I.e. write
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
to set, clear and test. This way you hide the magic numbers from the rest of your code.
Other than that, I endorse Paige Ruten's solution.
From snip-c.zip's bitops.h:
/*
** Bit set, clear, and test operations
**
** public domain snippet by Bob Stout
*/
typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
OK, let's analyze things...
The common expression that you seem to be having problems with in all of these is "(1L << (posn))". All this does is create a mask with a single bit on
and which will work with any integer type. The "posn" argument specifies the
position where you want the bit. If posn==0, then this expression will
evaluate to:
0000 0000 0000 0000 0000 0000 0000 0001 binary.
If posn==8, it will evaluate to:
0000 0000 0000 0000 0000 0001 0000 0000 binary.
In other words, it simply creates a field of 0's with a 1 at the specified
position. The only tricky part is in the BitClr() macro where we need to set
a single 0 bit in a field of 1's. This is accomplished by using the 1's
complement of the same expression as denoted by the tilde (~) operator.
Once the mask is created it's applied to the argument just as you suggest,
by use of the bitwise and (&), or (|), and xor (^) operators. Since the mask
is of type long, the macros will work just as well on char's, short's, int's,
or long's.
The bottom line is that this is a general solution to an entire class of
problems. It is, of course, possible and even appropriate to rewrite the
equivalent of any of these macros with explicit mask values every time you
need one, but why do it? Remember, the macro substitution occurs in the
preprocessor and so the generated code will reflect the fact that the values
are considered constant by the compiler - i.e. it's just as efficient to use
the generalized macros as to "reinvent the wheel" every time you need to do
bit manipulation.
Unconvinced? Here's some test code - I used Watcom C with full optimization
and without using _cdecl so the resulting disassembly would be as clean as
possible:
----[ TEST.C ]----------------------------------------------------------------
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
int bitmanip(int word)
{
word = BitSet(word, 2);
word = BitSet(word, 7);
word = BitClr(word, 3);
word = BitFlp(word, 9);
return word;
}
----[ TEST.OUT (disassembled) ]-----------------------------------------------
Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS
Segment: _TEXT BYTE 00000008 bytes
0000 0c 84 bitmanip_ or al,84H ; set bits 2 and 7
0002 80 f4 02 xor ah,02H ; flip bit 9 of EAX (bit 1 of AH)
0005 24 f7 and al,0f7H
0007 c3 ret
No disassembly errors
----[ finis ]-----------------------------------------------------------------
For the beginner I would like to explain a bit more with an example:
Example:
value is 0x55;
bitnum : 3rd.
The & operator is used check the bit:
0101 0101
&
0000 1000
___________
0000 0000 (mean 0: False). It will work fine if the third bit is 1 (then the answer will be True)
Toggle or Flip:
0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)
| operator: set the bit
0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)
As this is tagged "embedded" I'll assume you're using a microcontroller. All of the above suggestions are valid & work (read-modify-write, unions, structs, etc.).
However, during a bout of oscilloscope-based debugging I was amazed to find that these methods have a considerable overhead in CPU cycles compared to writing a value directly to the micro's PORTnSET / PORTnCLEAR registers which makes a real difference where there are tight loops / high-frequency ISR's toggling pins.
For those unfamiliar: In my example, the micro has a general pin-state register PORTn which reflects the output pins, so doing PORTn |= BIT_TO_SET results in a read-modify-write to that register. However, the PORTnSET / PORTnCLEAR registers take a '1' to mean "please make this bit 1" (SET) or "please make this bit zero" (CLEAR) and a '0' to mean "leave the pin alone". so, you end up with two port addresses depending whether you're setting or clearing the bit (not always convenient) but a much faster reaction and smaller assembled code.
Here's my favorite bit arithmetic macro, which works for any type of unsigned integer array from unsigned char up to size_t (which is the biggest type that should be efficient to work with):
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))
To set a bit:
BITOP(array, bit, |=);
To clear a bit:
BITOP(array, bit, &=~);
To toggle a bit:
BITOP(array, bit, ^=);
To test a bit:
if (BITOP(array, bit, &)) ...
etc.
Let suppose few things first
num = 55 Integer to perform bitwise operations (set, get, clear, toggle).
n = 4 0 based bit position to perform bitwise operations.
How to get a bit?
To get the nth bit of num right shift num, n times. Then perform bitwise AND & with 1.
bit = (num >> n) & 1;
How it works?
0011 0111 (55 in decimal)
>> 4 (right shift 4 times)
-----------------
0000 0011
& 0000 0001 (1 in decimal)
-----------------
=> 0000 0001 (final result)
How to set a bit?
To set a particular bit of number. Left shift 1 n times. Then perform bitwise OR | operation with num.
num |= (1 << n); // Equivalent to; num = (1 << n) | num;
How it works?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
| 0011 0111 (55 in decimal)
-----------------
=> 0001 0000 (final result)
How to clear a bit?
Left shift 1, n times i.e. 1 << n.
Perform bitwise complement with the above result. So that the nth bit becomes unset and rest of bit becomes set i.e. ~ (1 << n).
Finally, perform bitwise AND & operation with the above result and num. The above three steps together can be written as num & (~ (1 << n));
num &= (~(1 << n)); // Equivalent to; num = num & (~(1 << n));
How it works?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
~ 0001 0000
-----------------
1110 1111
& 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
How to toggle a bit?
To toggle a bit we use bitwise XOR ^ operator. Bitwise XOR operator evaluates to 1 if corresponding bit of both operands are different, otherwise evaluates to 0.
Which means to toggle a bit, we need to perform XOR operation with the bit you want to toggle and 1.
num ^= (1 << n); // Equivalent to; num = num ^ (1 << n);
How it works?
If the bit to toggle is 0 then, 0 ^ 1 => 1.
If the bit to toggle is 1 then, 1 ^ 1 => 0.
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
^ 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
Recommended reading - Bitwise operator exercises
The bitfield approach has other advantages in the embedded arena. You can define a struct that maps directly onto the bits in a particular hardware register.
struct HwRegister {
unsigned int errorFlag:1; // one-bit flag field
unsigned int Mode:3; // three-bit mode field
unsigned int StatusCode:4; // four-bit status code
};
struct HwRegister CR3342_AReg;
You need to be aware of the bit packing order - I think it's MSB first, but this may be implementation-dependent. Also, verify how your compiler handlers fields crossing byte boundaries.
You can then read, write, test the individual values as before.
Check a bit at an arbitrary location in a variable of arbitrary type:
#define bit_test(x, y) ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )
Sample usage:
int main(void)
{
unsigned char arr[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
for (int ix = 0; ix < 64; ++ix)
printf("bit %d is %d\n", ix, bit_test(arr, ix));
return 0;
}
Notes:
This is designed to be fast (given its flexibility) and non-branchy. It results in efficient SPARC machine code when compiled Sun Studio 8; I've also tested it using MSVC++ 2008 on amd64. It's possible to make similar macros for setting and clearing bits. The key difference of this solution compared with many others here is that it works for any location in pretty much any type of variable.
More general, for arbitrary sized bitmaps:
#define BITS 8
#define BIT_SET( p, n) (p[(n)/BITS] |= (0x80>>((n)%BITS)))
#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS)))
#define BIT_ISSET(p, n) (p[(n)/BITS] & (0x80>>((n)%BITS)))
This program is to change any data bit from 0 to 1 or 1 to 0:
{
unsigned int data = 0x000000F0;
int bitpos = 4;
int bitvalue = 1;
unsigned int bit = data;
bit = (bit>>bitpos)&0x00000001;
int invbitvalue = 0x00000001&(~bitvalue);
printf("%x\n",bit);
if (bitvalue == 0)
{
if (bit == 0)
printf("%x\n", data);
else
{
data = (data^(invbitvalue<<bitpos));
printf("%x\n", data);
}
}
else
{
if (bit == 1)
printf("elseif %x\n", data);
else
{
data = (data|(bitvalue<<bitpos));
printf("else %x\n", data);
}
}
}
If you're doing a lot of bit twiddling you might want to use masks which will make the whole thing quicker. The following functions are very fast and are still flexible (they allow bit twiddling in bit maps of any size).
const unsigned char TQuickByteMask[8] =
{
0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80,
};
/** Set bit in any sized bit mask.
*
* #return none
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TSetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] |= TQuickByteMask[n]; // Set bit.
}
/** Reset bit in any sized mask.
*
* #return None
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TResetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] &= (~TQuickByteMask[n]); // Reset bit.
}
/** Toggle bit in any sized bit mask.
*
* #return none
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TToggleBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] ^= TQuickByteMask[n]; // Toggle bit.
}
/** Checks specified bit.
*
* #return 1 if bit set else 0.
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
short TIsBitSet( short bit, const unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
// Test bit (logigal AND).
if (bitmap[x] & TQuickByteMask[n])
return 1;
return 0;
}
/** Checks specified bit.
*
* #return 1 if bit reset else 0.
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
short TIsBitReset( short bit, const unsigned char *bitmap)
{
return TIsBitSet(bit, bitmap) ^ 1;
}
/** Count number of bits set in a bitmap.
*
* #return Number of bits set.
*
* #param bitmap - Pointer to bitmap.
* #param size - Bitmap size (in bits).
*
* #note Not very efficient in terms of execution speed. If you are doing
* some computationally intense stuff you may need a more complex
* implementation which would be faster (especially for big bitmaps).
* See (http://graphics.stanford.edu/~seander/bithacks.html).
*/
int TCountBits( const unsigned char *bitmap, int size)
{
int i, count = 0;
for (i=0; i<size; i++)
if (TIsBitSet(i, bitmap))
count++;
return count;
}
Note, to set bit 'n' in a 16 bit integer you do the following:
TSetBit( n, &my_int);
It's up to you to ensure that the bit number is within the range of the bit map that you pass. Note that for little endian processors that bytes, words, dwords, qwords, etc., map correctly to each other in memory (main reason that little endian processors are 'better' than big-endian processors, ah, I feel a flame war coming on...).
Use this:
int ToggleNthBit ( unsigned char n, int num )
{
if(num & (1 << n))
num &= ~(1 << n);
else
num |= (1 << n);
return num;
}
Expanding on the bitset answer:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
bitset<8> byte(std::string("10010011");
// Set Bit
byte.set(3); // 10010111
// Clear Bit
byte.reset(2); // 10010101
// Toggle Bit
byte.flip(7); // 00010101
cout << byte << endl;
return 0;
}
If you want to perform this all operation with C programming in the Linux kernel then I suggest to use standard APIs of the Linux kernel.
See https://www.kernel.org/doc/htmldocs/kernel-api/ch02s03.html
set_bit Atomically set a bit in memory
clear_bit Clears a bit in memory
change_bit Toggle a bit in memory
test_and_set_bit Set a bit and return its old value
test_and_clear_bit Clear a bit and return its old value
test_and_change_bit Change a bit and return its old value
test_bit Determine whether a bit is set
Note: Here the whole operation happens in a single step. So these all are guaranteed to be atomic even on SMP computers and are useful
to keep coherence across processors.
Visual C 2010, and perhaps many other compilers, have direct support for boolean operations built in. A bit has two possible values, just like a boolean, so we can use booleans instead - even if they take up more space than a single bit in memory in this representation. This works, even the sizeof() operator works properly.
bool IsGph[256], IsNotGph[256];
// Initialize boolean array to detect printable characters
for(i=0; i<sizeof(IsGph); i++) {
IsGph[i] = isgraph((unsigned char)i);
}
So, to your question, IsGph[i] =1, or IsGph[i] =0 make setting and clearing bools easy.
To find unprintable characters:
// Initialize boolean array to detect UN-printable characters,
// then call function to toggle required bits true, while initializing a 2nd
// boolean array as the complement of the 1st.
for(i=0; i<sizeof(IsGph); i++) {
if(IsGph[i]) {
IsNotGph[i] = 0;
} else {
IsNotGph[i] = 1;
}
}
Note there is nothing "special" about this code. It treats a bit like an integer - which technically, it is. A 1 bit integer that can hold 2 values, and 2 values only.
I once used this approach to find duplicate loan records, where loan_number was the ISAM key, using the 6-digit loan number as an index into the bit array. Savagely fast, and after 8 months, proved that the mainframe system we were getting the data from was in fact malfunctioning. The simplicity of bit arrays makes confidence in their correctness very high - vs a searching approach for example.
int set_nth_bit(int num, int n){
return (num | 1 << n);
}
int clear_nth_bit(int num, int n){
return (num & ~( 1 << n));
}
int toggle_nth_bit(int num, int n){
return num ^ (1 << n);
}
int check_nth_bit(int num, int n){
return num & (1 << n);
}
Here are some macros I use:
SET_FLAG(Status, Flag) ((Status) |= (Flag))
CLEAR_FLAG(Status, Flag) ((Status) &= ~(Flag))
INVALID_FLAGS(ulFlags, ulAllowed) ((ulFlags) & ~(ulAllowed))
TEST_FLAGS(t,ulMask, ulBit) (((t)&(ulMask)) == (ulBit))
IS_FLAG_SET(t,ulMask) TEST_FLAGS(t,ulMask,ulMask)
IS_FLAG_CLEAR(t,ulMask) TEST_FLAGS(t,ulMask,0)
How do you set, clear, and toggle a single bit?
To address a common coding pitfall when attempting to form the mask:
1 is not always wide enough
What problems happen when number is a wider type than 1?
x may be too great for the shift 1 << x leading to undefined behavior (UB). Even if x is not too great, ~ may not flip enough most-significant-bits.
// assume 32 bit int/unsigned
unsigned long long number = foo();
unsigned x = 40;
number |= (1 << x); // UB
number ^= (1 << x); // UB
number &= ~(1 << x); // UB
x = 10;
number &= ~(1 << x); // Wrong mask, not wide enough
To insure 1 is wide enough:
Code could use 1ull or pedantically (uintmax_t)1 and let the compiler optimize.
number |= (1ull << x);
number |= ((uintmax_t)1 << x);
Or cast - which makes for coding/review/maintenance issues keeping the cast correct and up-to-date.
number |= (type_of_number)1 << x;
Or gently promote the 1 by forcing a math operation that is as least as wide as the type of number.
number |= (number*0 + 1) << x;
As with most bit manipulations, best to work with unsigned types rather than signed ones
This program is based out of #Jeremy's above solution. If someone wish to quickly play around.
public class BitwiseOperations {
public static void main(String args[]) {
setABit(0, 4); // set the 4th bit, 0000 -> 1000 [8]
clearABit(16, 5); // clear the 5th bit, 10000 -> 00000 [0]
toggleABit(8, 4); // toggle the 4th bit, 1000 -> 0000 [0]
checkABit(8,4); // check the 4th bit 1000 -> true
}
public static void setABit(int input, int n) {
input = input | ( 1 << n-1);
System.out.println(input);
}
public static void clearABit(int input, int n) {
input = input & ~(1 << n-1);
System.out.println(input);
}
public static void toggleABit(int input, int n) {
input = input ^ (1 << n-1);
System.out.println(input);
}
public static void checkABit(int input, int n) {
boolean isSet = ((input >> n-1) & 1) == 1;
System.out.println(isSet);
}
}
Output :
8
0
0
true
A templated version (put in a header file) with support for changing multiple bits (works on AVR microcontrollers btw):
namespace bit {
template <typename T1, typename T2>
constexpr inline T1 bitmask(T2 bit)
{return (T1)1 << bit;}
template <typename T1, typename T3, typename ...T2>
constexpr inline T1 bitmask(T3 bit, T2 ...bits)
{return ((T1)1 << bit) | bitmask<T1>(bits...);}
/** Set these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void set (T1 &variable, T2 ...bits)
{variable |= bitmask<T1>(bits...);}
/** Set only these bits (others will be cleared) */
template <typename T1, typename ...T2>
constexpr inline void setOnly (T1 &variable, T2 ...bits)
{variable = bitmask<T1>(bits...);}
/** Clear these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void clear (T1 &variable, T2 ...bits)
{variable &= ~bitmask<T1>(bits...);}
/** Flip these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void flip (T1 &variable, T2 ...bits)
{variable ^= bitmask<T1>(bits...);}
/** Check if any of these bits are set */
template <typename T1, typename ...T2>
constexpr inline bool isAnySet(const T1 &variable, T2 ...bits)
{return variable & bitmask<T1>(bits...);}
/** Check if all these bits are set */
template <typename T1, typename ...T2>
constexpr inline bool isSet (const T1 &variable, T2 ...bits)
{return ((variable & bitmask<T1>(bits...)) == bitmask<T1>(bits...));}
/** Check if all these bits are not set */
template <typename T1, typename ...T2>
constexpr inline bool isNotSet (const T1 &variable, T2 ...bits)
{return ((variable & bitmask<T1>(bits...)) != bitmask<T1>(bits...));}
}
Example of use:
#include <iostream>
#include <bitset> // for console output of binary values
// and include the code above of course
using namespace std;
int main() {
uint8_t v = 0b1111'1100;
bit::set(v, 0);
cout << bitset<8>(v) << endl;
bit::clear(v, 0,1);
cout << bitset<8>(v) << endl;
bit::flip(v, 0,1);
cout << bitset<8>(v) << endl;
bit::clear(v, 0,1,2,3,4,5,6,7);
cout << bitset<8>(v) << endl;
bit::flip(v, 0,7);
cout << bitset<8>(v) << endl;
}
BTW: It turns out that constexpr and inline is not used if not sending the optimizer argument (e.g.: -O3) to the compiler. Feel free to try the code at https://godbolt.org/ and look at the ASM output.
Here is a routine in C to perform the basic bitwise operations:
#define INT_BIT (unsigned int) (sizeof(unsigned int) * 8U) //number of bits in unsigned int
int main(void)
{
unsigned int k = 5; //k is the bit position; here it is the 5th bit from the LSb (0th bit)
unsigned int regA = 0x00007C7C; //we perform bitwise operations on regA
regA |= (1U << k); //Set kth bit
regA &= ~(1U << k); //Clear kth bit
regA ^= (1U << k); //Toggle kth bit
regA = (regA << k) | regA >> (INT_BIT - k); //Rotate left by k bits
regA = (regA >> k) | regA << (INT_BIT - k); //Rotate right by k bits
return 0;
}
Setting the nth bit to x (bit value) without using -1
Sometimes when you are not sure what -1 or the like will result in, you may wish to set the nth bit without using -1:
number = (((number | (1 << n)) ^ (1 << n))) | (x << n);
Explanation: ((number | (1 << n) sets the nth bit to 1 (where | denotes bitwise OR), then with (...) ^ (1 << n) we set the nth bit to 0, and finally with (...) | x << n) we set the nth bit that was 0, to (bit value) x.
This also works in golang.
Try one of these functions in the C language to change n bit:
char bitfield;
// Start at 0th position
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}
Or
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}
Or
void chang_n_bit(int n, int value)
{
if(value)
bitfield |= 1 << n;
else
bitfield &= ~0 ^ (1 << n);
}
char get_n_bit(int n)
{
return (bitfield & (1 << n)) ? 1 : 0;
}
How do I set, clear, and toggle a bit?
Setting a bit
Use the bitwise OR operator (|) to set a bit.
number |= 1UL << n;
That will set the nth bit of number. n should be zero, if you want to set the 1st bit and so on upto n-1, if you want to set the nth bit.
Use 1ULL if number is wider than unsigned long; promotion of 1UL << n doesn't happen until after evaluating 1UL << n where it's undefined behaviour to shift by more than the width of a long. The same applies to all the rest of the examples.
Clearing a bit
Use the bitwise AND operator (&) to clear a bit.
number &= ~(1UL << n);
That will clear the nth bit of number. You must invert the bit string with the bitwise NOT operator (~), then AND it.
Toggling a bit
The XOR operator (^) can be used to toggle a bit.
number ^= 1UL << n;
That will toggle the nth bit of number.
Checking a bit
You didn't ask for this, but I might as well add it.
To check a bit, shift the number n to the right, then bitwise AND it:
bit = (number >> n) & 1U;
That will put the value of the nth bit of number into the variable bit.
Changing the nth bit to x
Setting the nth bit to either 1 or 0 can be achieved with the following on a 2's complement C++ implementation:
number ^= (-x ^ number) & (1UL << n);
Bit n will be set if x is 1, and cleared if x is 0. If x has some other value, you get garbage. x = !!x will booleanize it to 0 or 1.
To make this independent of 2's complement negation behaviour (where -1 has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
or
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
It's generally a good idea to use unsigned types for portable bit manipulation.
or
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n)) will clear the nth bit and (x << n) will set the nth bit to x.
It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down) or some sort of encapsulation.
Using the Standard C++ Library: std::bitset<N>.
Or the Boost version: boost::dynamic_bitset.
There is no need to roll your own:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x;
x[1] = 1;
x[2] = 0;
// Note x[0-4] valid
std::cout << x << std::endl;
}
[Alpha:] > ./a.out
00010
The Boost version allows a runtime sized bitset compared with a standard library compile-time sized bitset.
The other option is to use bit fields:
struct bits {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
};
struct bits mybits;
defines a 3-bit field (actually, it's three 1-bit felds). Bit operations now become a bit (haha) simpler:
To set or clear a bit:
mybits.b = 1;
mybits.c = 0;
To toggle a bit:
mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1; /* all work */
Checking a bit:
if (mybits.c) //if mybits.c is non zero the next line below will execute
This only works with fixed-size bit fields. Otherwise you have to resort to the bit-twiddling techniques described in previous posts.
I use macros defined in a header file to handle bit set and clear:
/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1
#define BITMASK_SET(x, mask) ((x) |= (mask))
#define BITMASK_CLEAR(x, mask) ((x) &= (~(mask)))
#define BITMASK_FLIP(x, mask) ((x) ^= (mask))
#define BITMASK_CHECK_ALL(x, mask) (!(~(x) & (mask)))
#define BITMASK_CHECK_ANY(x, mask) ((x) & (mask))
It is sometimes worth using an enum to name the bits:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Then use the names later on. I.e. write
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
to set, clear and test. This way you hide the magic numbers from the rest of your code.
Other than that, I endorse Paige Ruten's solution.
From snip-c.zip's bitops.h:
/*
** Bit set, clear, and test operations
**
** public domain snippet by Bob Stout
*/
typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
OK, let's analyze things...
The common expression that you seem to be having problems with in all of these is "(1L << (posn))". All this does is create a mask with a single bit on
and which will work with any integer type. The "posn" argument specifies the
position where you want the bit. If posn==0, then this expression will
evaluate to:
0000 0000 0000 0000 0000 0000 0000 0001 binary.
If posn==8, it will evaluate to:
0000 0000 0000 0000 0000 0001 0000 0000 binary.
In other words, it simply creates a field of 0's with a 1 at the specified
position. The only tricky part is in the BitClr() macro where we need to set
a single 0 bit in a field of 1's. This is accomplished by using the 1's
complement of the same expression as denoted by the tilde (~) operator.
Once the mask is created it's applied to the argument just as you suggest,
by use of the bitwise and (&), or (|), and xor (^) operators. Since the mask
is of type long, the macros will work just as well on char's, short's, int's,
or long's.
The bottom line is that this is a general solution to an entire class of
problems. It is, of course, possible and even appropriate to rewrite the
equivalent of any of these macros with explicit mask values every time you
need one, but why do it? Remember, the macro substitution occurs in the
preprocessor and so the generated code will reflect the fact that the values
are considered constant by the compiler - i.e. it's just as efficient to use
the generalized macros as to "reinvent the wheel" every time you need to do
bit manipulation.
Unconvinced? Here's some test code - I used Watcom C with full optimization
and without using _cdecl so the resulting disassembly would be as clean as
possible:
----[ TEST.C ]----------------------------------------------------------------
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
int bitmanip(int word)
{
word = BitSet(word, 2);
word = BitSet(word, 7);
word = BitClr(word, 3);
word = BitFlp(word, 9);
return word;
}
----[ TEST.OUT (disassembled) ]-----------------------------------------------
Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS
Segment: _TEXT BYTE 00000008 bytes
0000 0c 84 bitmanip_ or al,84H ; set bits 2 and 7
0002 80 f4 02 xor ah,02H ; flip bit 9 of EAX (bit 1 of AH)
0005 24 f7 and al,0f7H
0007 c3 ret
No disassembly errors
----[ finis ]-----------------------------------------------------------------
For the beginner I would like to explain a bit more with an example:
Example:
value is 0x55;
bitnum : 3rd.
The & operator is used check the bit:
0101 0101
&
0000 1000
___________
0000 0000 (mean 0: False). It will work fine if the third bit is 1 (then the answer will be True)
Toggle or Flip:
0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)
| operator: set the bit
0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)
As this is tagged "embedded" I'll assume you're using a microcontroller. All of the above suggestions are valid & work (read-modify-write, unions, structs, etc.).
However, during a bout of oscilloscope-based debugging I was amazed to find that these methods have a considerable overhead in CPU cycles compared to writing a value directly to the micro's PORTnSET / PORTnCLEAR registers which makes a real difference where there are tight loops / high-frequency ISR's toggling pins.
For those unfamiliar: In my example, the micro has a general pin-state register PORTn which reflects the output pins, so doing PORTn |= BIT_TO_SET results in a read-modify-write to that register. However, the PORTnSET / PORTnCLEAR registers take a '1' to mean "please make this bit 1" (SET) or "please make this bit zero" (CLEAR) and a '0' to mean "leave the pin alone". so, you end up with two port addresses depending whether you're setting or clearing the bit (not always convenient) but a much faster reaction and smaller assembled code.
Here's my favorite bit arithmetic macro, which works for any type of unsigned integer array from unsigned char up to size_t (which is the biggest type that should be efficient to work with):
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))
To set a bit:
BITOP(array, bit, |=);
To clear a bit:
BITOP(array, bit, &=~);
To toggle a bit:
BITOP(array, bit, ^=);
To test a bit:
if (BITOP(array, bit, &)) ...
etc.
Let suppose few things first
num = 55 Integer to perform bitwise operations (set, get, clear, toggle).
n = 4 0 based bit position to perform bitwise operations.
How to get a bit?
To get the nth bit of num right shift num, n times. Then perform bitwise AND & with 1.
bit = (num >> n) & 1;
How it works?
0011 0111 (55 in decimal)
>> 4 (right shift 4 times)
-----------------
0000 0011
& 0000 0001 (1 in decimal)
-----------------
=> 0000 0001 (final result)
How to set a bit?
To set a particular bit of number. Left shift 1 n times. Then perform bitwise OR | operation with num.
num |= (1 << n); // Equivalent to; num = (1 << n) | num;
How it works?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
| 0011 0111 (55 in decimal)
-----------------
=> 0001 0000 (final result)
How to clear a bit?
Left shift 1, n times i.e. 1 << n.
Perform bitwise complement with the above result. So that the nth bit becomes unset and rest of bit becomes set i.e. ~ (1 << n).
Finally, perform bitwise AND & operation with the above result and num. The above three steps together can be written as num & (~ (1 << n));
num &= (~(1 << n)); // Equivalent to; num = num & (~(1 << n));
How it works?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
~ 0001 0000
-----------------
1110 1111
& 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
How to toggle a bit?
To toggle a bit we use bitwise XOR ^ operator. Bitwise XOR operator evaluates to 1 if corresponding bit of both operands are different, otherwise evaluates to 0.
Which means to toggle a bit, we need to perform XOR operation with the bit you want to toggle and 1.
num ^= (1 << n); // Equivalent to; num = num ^ (1 << n);
How it works?
If the bit to toggle is 0 then, 0 ^ 1 => 1.
If the bit to toggle is 1 then, 1 ^ 1 => 0.
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
^ 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
Recommended reading - Bitwise operator exercises
The bitfield approach has other advantages in the embedded arena. You can define a struct that maps directly onto the bits in a particular hardware register.
struct HwRegister {
unsigned int errorFlag:1; // one-bit flag field
unsigned int Mode:3; // three-bit mode field
unsigned int StatusCode:4; // four-bit status code
};
struct HwRegister CR3342_AReg;
You need to be aware of the bit packing order - I think it's MSB first, but this may be implementation-dependent. Also, verify how your compiler handlers fields crossing byte boundaries.
You can then read, write, test the individual values as before.
Check a bit at an arbitrary location in a variable of arbitrary type:
#define bit_test(x, y) ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )
Sample usage:
int main(void)
{
unsigned char arr[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
for (int ix = 0; ix < 64; ++ix)
printf("bit %d is %d\n", ix, bit_test(arr, ix));
return 0;
}
Notes:
This is designed to be fast (given its flexibility) and non-branchy. It results in efficient SPARC machine code when compiled Sun Studio 8; I've also tested it using MSVC++ 2008 on amd64. It's possible to make similar macros for setting and clearing bits. The key difference of this solution compared with many others here is that it works for any location in pretty much any type of variable.
More general, for arbitrary sized bitmaps:
#define BITS 8
#define BIT_SET( p, n) (p[(n)/BITS] |= (0x80>>((n)%BITS)))
#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS)))
#define BIT_ISSET(p, n) (p[(n)/BITS] & (0x80>>((n)%BITS)))
This program is to change any data bit from 0 to 1 or 1 to 0:
{
unsigned int data = 0x000000F0;
int bitpos = 4;
int bitvalue = 1;
unsigned int bit = data;
bit = (bit>>bitpos)&0x00000001;
int invbitvalue = 0x00000001&(~bitvalue);
printf("%x\n",bit);
if (bitvalue == 0)
{
if (bit == 0)
printf("%x\n", data);
else
{
data = (data^(invbitvalue<<bitpos));
printf("%x\n", data);
}
}
else
{
if (bit == 1)
printf("elseif %x\n", data);
else
{
data = (data|(bitvalue<<bitpos));
printf("else %x\n", data);
}
}
}
If you're doing a lot of bit twiddling you might want to use masks which will make the whole thing quicker. The following functions are very fast and are still flexible (they allow bit twiddling in bit maps of any size).
const unsigned char TQuickByteMask[8] =
{
0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80,
};
/** Set bit in any sized bit mask.
*
* #return none
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TSetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] |= TQuickByteMask[n]; // Set bit.
}
/** Reset bit in any sized mask.
*
* #return None
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TResetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] &= (~TQuickByteMask[n]); // Reset bit.
}
/** Toggle bit in any sized bit mask.
*
* #return none
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TToggleBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] ^= TQuickByteMask[n]; // Toggle bit.
}
/** Checks specified bit.
*
* #return 1 if bit set else 0.
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
short TIsBitSet( short bit, const unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
// Test bit (logigal AND).
if (bitmap[x] & TQuickByteMask[n])
return 1;
return 0;
}
/** Checks specified bit.
*
* #return 1 if bit reset else 0.
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
short TIsBitReset( short bit, const unsigned char *bitmap)
{
return TIsBitSet(bit, bitmap) ^ 1;
}
/** Count number of bits set in a bitmap.
*
* #return Number of bits set.
*
* #param bitmap - Pointer to bitmap.
* #param size - Bitmap size (in bits).
*
* #note Not very efficient in terms of execution speed. If you are doing
* some computationally intense stuff you may need a more complex
* implementation which would be faster (especially for big bitmaps).
* See (http://graphics.stanford.edu/~seander/bithacks.html).
*/
int TCountBits( const unsigned char *bitmap, int size)
{
int i, count = 0;
for (i=0; i<size; i++)
if (TIsBitSet(i, bitmap))
count++;
return count;
}
Note, to set bit 'n' in a 16 bit integer you do the following:
TSetBit( n, &my_int);
It's up to you to ensure that the bit number is within the range of the bit map that you pass. Note that for little endian processors that bytes, words, dwords, qwords, etc., map correctly to each other in memory (main reason that little endian processors are 'better' than big-endian processors, ah, I feel a flame war coming on...).
Use this:
int ToggleNthBit ( unsigned char n, int num )
{
if(num & (1 << n))
num &= ~(1 << n);
else
num |= (1 << n);
return num;
}
Expanding on the bitset answer:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
bitset<8> byte(std::string("10010011");
// Set Bit
byte.set(3); // 10010111
// Clear Bit
byte.reset(2); // 10010101
// Toggle Bit
byte.flip(7); // 00010101
cout << byte << endl;
return 0;
}
If you want to perform this all operation with C programming in the Linux kernel then I suggest to use standard APIs of the Linux kernel.
See https://www.kernel.org/doc/htmldocs/kernel-api/ch02s03.html
set_bit Atomically set a bit in memory
clear_bit Clears a bit in memory
change_bit Toggle a bit in memory
test_and_set_bit Set a bit and return its old value
test_and_clear_bit Clear a bit and return its old value
test_and_change_bit Change a bit and return its old value
test_bit Determine whether a bit is set
Note: Here the whole operation happens in a single step. So these all are guaranteed to be atomic even on SMP computers and are useful
to keep coherence across processors.
Visual C 2010, and perhaps many other compilers, have direct support for boolean operations built in. A bit has two possible values, just like a boolean, so we can use booleans instead - even if they take up more space than a single bit in memory in this representation. This works, even the sizeof() operator works properly.
bool IsGph[256], IsNotGph[256];
// Initialize boolean array to detect printable characters
for(i=0; i<sizeof(IsGph); i++) {
IsGph[i] = isgraph((unsigned char)i);
}
So, to your question, IsGph[i] =1, or IsGph[i] =0 make setting and clearing bools easy.
To find unprintable characters:
// Initialize boolean array to detect UN-printable characters,
// then call function to toggle required bits true, while initializing a 2nd
// boolean array as the complement of the 1st.
for(i=0; i<sizeof(IsGph); i++) {
if(IsGph[i]) {
IsNotGph[i] = 0;
} else {
IsNotGph[i] = 1;
}
}
Note there is nothing "special" about this code. It treats a bit like an integer - which technically, it is. A 1 bit integer that can hold 2 values, and 2 values only.
I once used this approach to find duplicate loan records, where loan_number was the ISAM key, using the 6-digit loan number as an index into the bit array. Savagely fast, and after 8 months, proved that the mainframe system we were getting the data from was in fact malfunctioning. The simplicity of bit arrays makes confidence in their correctness very high - vs a searching approach for example.
int set_nth_bit(int num, int n){
return (num | 1 << n);
}
int clear_nth_bit(int num, int n){
return (num & ~( 1 << n));
}
int toggle_nth_bit(int num, int n){
return num ^ (1 << n);
}
int check_nth_bit(int num, int n){
return num & (1 << n);
}
Here are some macros I use:
SET_FLAG(Status, Flag) ((Status) |= (Flag))
CLEAR_FLAG(Status, Flag) ((Status) &= ~(Flag))
INVALID_FLAGS(ulFlags, ulAllowed) ((ulFlags) & ~(ulAllowed))
TEST_FLAGS(t,ulMask, ulBit) (((t)&(ulMask)) == (ulBit))
IS_FLAG_SET(t,ulMask) TEST_FLAGS(t,ulMask,ulMask)
IS_FLAG_CLEAR(t,ulMask) TEST_FLAGS(t,ulMask,0)
How do you set, clear, and toggle a single bit?
To address a common coding pitfall when attempting to form the mask:
1 is not always wide enough
What problems happen when number is a wider type than 1?
x may be too great for the shift 1 << x leading to undefined behavior (UB). Even if x is not too great, ~ may not flip enough most-significant-bits.
// assume 32 bit int/unsigned
unsigned long long number = foo();
unsigned x = 40;
number |= (1 << x); // UB
number ^= (1 << x); // UB
number &= ~(1 << x); // UB
x = 10;
number &= ~(1 << x); // Wrong mask, not wide enough
To insure 1 is wide enough:
Code could use 1ull or pedantically (uintmax_t)1 and let the compiler optimize.
number |= (1ull << x);
number |= ((uintmax_t)1 << x);
Or cast - which makes for coding/review/maintenance issues keeping the cast correct and up-to-date.
number |= (type_of_number)1 << x;
Or gently promote the 1 by forcing a math operation that is as least as wide as the type of number.
number |= (number*0 + 1) << x;
As with most bit manipulations, best to work with unsigned types rather than signed ones
This program is based out of #Jeremy's above solution. If someone wish to quickly play around.
public class BitwiseOperations {
public static void main(String args[]) {
setABit(0, 4); // set the 4th bit, 0000 -> 1000 [8]
clearABit(16, 5); // clear the 5th bit, 10000 -> 00000 [0]
toggleABit(8, 4); // toggle the 4th bit, 1000 -> 0000 [0]
checkABit(8,4); // check the 4th bit 1000 -> true
}
public static void setABit(int input, int n) {
input = input | ( 1 << n-1);
System.out.println(input);
}
public static void clearABit(int input, int n) {
input = input & ~(1 << n-1);
System.out.println(input);
}
public static void toggleABit(int input, int n) {
input = input ^ (1 << n-1);
System.out.println(input);
}
public static void checkABit(int input, int n) {
boolean isSet = ((input >> n-1) & 1) == 1;
System.out.println(isSet);
}
}
Output :
8
0
0
true
A templated version (put in a header file) with support for changing multiple bits (works on AVR microcontrollers btw):
namespace bit {
template <typename T1, typename T2>
constexpr inline T1 bitmask(T2 bit)
{return (T1)1 << bit;}
template <typename T1, typename T3, typename ...T2>
constexpr inline T1 bitmask(T3 bit, T2 ...bits)
{return ((T1)1 << bit) | bitmask<T1>(bits...);}
/** Set these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void set (T1 &variable, T2 ...bits)
{variable |= bitmask<T1>(bits...);}
/** Set only these bits (others will be cleared) */
template <typename T1, typename ...T2>
constexpr inline void setOnly (T1 &variable, T2 ...bits)
{variable = bitmask<T1>(bits...);}
/** Clear these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void clear (T1 &variable, T2 ...bits)
{variable &= ~bitmask<T1>(bits...);}
/** Flip these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void flip (T1 &variable, T2 ...bits)
{variable ^= bitmask<T1>(bits...);}
/** Check if any of these bits are set */
template <typename T1, typename ...T2>
constexpr inline bool isAnySet(const T1 &variable, T2 ...bits)
{return variable & bitmask<T1>(bits...);}
/** Check if all these bits are set */
template <typename T1, typename ...T2>
constexpr inline bool isSet (const T1 &variable, T2 ...bits)
{return ((variable & bitmask<T1>(bits...)) == bitmask<T1>(bits...));}
/** Check if all these bits are not set */
template <typename T1, typename ...T2>
constexpr inline bool isNotSet (const T1 &variable, T2 ...bits)
{return ((variable & bitmask<T1>(bits...)) != bitmask<T1>(bits...));}
}
Example of use:
#include <iostream>
#include <bitset> // for console output of binary values
// and include the code above of course
using namespace std;
int main() {
uint8_t v = 0b1111'1100;
bit::set(v, 0);
cout << bitset<8>(v) << endl;
bit::clear(v, 0,1);
cout << bitset<8>(v) << endl;
bit::flip(v, 0,1);
cout << bitset<8>(v) << endl;
bit::clear(v, 0,1,2,3,4,5,6,7);
cout << bitset<8>(v) << endl;
bit::flip(v, 0,7);
cout << bitset<8>(v) << endl;
}
BTW: It turns out that constexpr and inline is not used if not sending the optimizer argument (e.g.: -O3) to the compiler. Feel free to try the code at https://godbolt.org/ and look at the ASM output.
Here is a routine in C to perform the basic bitwise operations:
#define INT_BIT (unsigned int) (sizeof(unsigned int) * 8U) //number of bits in unsigned int
int main(void)
{
unsigned int k = 5; //k is the bit position; here it is the 5th bit from the LSb (0th bit)
unsigned int regA = 0x00007C7C; //we perform bitwise operations on regA
regA |= (1U << k); //Set kth bit
regA &= ~(1U << k); //Clear kth bit
regA ^= (1U << k); //Toggle kth bit
regA = (regA << k) | regA >> (INT_BIT - k); //Rotate left by k bits
regA = (regA >> k) | regA << (INT_BIT - k); //Rotate right by k bits
return 0;
}
Setting the nth bit to x (bit value) without using -1
Sometimes when you are not sure what -1 or the like will result in, you may wish to set the nth bit without using -1:
number = (((number | (1 << n)) ^ (1 << n))) | (x << n);
Explanation: ((number | (1 << n) sets the nth bit to 1 (where | denotes bitwise OR), then with (...) ^ (1 << n) we set the nth bit to 0, and finally with (...) | x << n) we set the nth bit that was 0, to (bit value) x.
This also works in golang.
Try one of these functions in the C language to change n bit:
char bitfield;
// Start at 0th position
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}
Or
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}
Or
void chang_n_bit(int n, int value)
{
if(value)
bitfield |= 1 << n;
else
bitfield &= ~0 ^ (1 << n);
}
char get_n_bit(int n)
{
return (bitfield & (1 << n)) ? 1 : 0;
}
I just tried with this code:
void swapBit(unsigned char* numbA, unsigned char* numbB, short bitPosition)//bitPosition 0-x
{
unsigned char oneShift = 1 << bitPosition;
unsigned char bitA = *numbA & oneShift;
unsigned char bitB = *numbB & oneShift;
if (bitA)
*numbB |= bitA;
else
*numbB &= (~bitA ^ oneShift);
if (bitB)
*numbA |= bitB;
else
*numbA &= (~bitB ^ oneShift);
}
to swap bit position x of a and b but because of the if() I think there's something better.
Also when i see this:
*numbB &= (~bitA ^ oneShift);
I really think that there's an easier way to do it.
If you have something for me, i would take it :)
Thanks in advance
First you should set the corresponding position in a number to 0, and then OR it with the actual bit, removing all of the conditions:
*numbB &= ~oneShift; // Set the bit to `0`
*numbB |= bitA; // Set to the actual bit value
The same for the other number.
A single bit is no easier than an arbitrary bitmask, so lets just talk about that. You can always call this function with 1U << bitpos.
If a bit position is the same in both values, no change is needed in either. If it's opposite, they both need to invert.
XOR with 1 flips a bit; XOR with 0 is a no-op.
So what we want is a value that has a 1 everywhere there's a bit-difference between the inputs, and a 0 everywhere else. That's exactly what a XOR b does. Simply mask this to only swap some of the bits, and we have a bit-swap in 3 XORs + 1 AND.
// call with unsigned char mask = 1U << bitPosition; if you want
inline
void swapBit_char(unsigned char *A, unsigned char *B, unsigned char mask)
{
unsigned char tmpA = *A, tmpB = *B; // read into locals in case A==B
unsigned char bitdiff = tmpA ^ tmpB;
bitdiff &= mask; // only swap bits matching the mask
*A = tmpA ^ bitdiff;
*B = tmpB ^ bitdiff;
}
(Godbolt compiler explorer with gcc for x86-64 and ARM, includes a version with unsigned instead of unsigned char.)
You could consider if(bitdiff) { ... }, but unless you're going to avoid dirtying a cache line in memory by avoiding the assignments, it's probably not worth doing any conditional behaviour. With values in registers (after inlining), a branch to save two xor instructions is almost never worth it.
This is not an xor-swap. It does use temporary storage. As #chux's answer demonstrates, a masked xor-swap requires 3 AND operations as well as 3 XOR. (And defeats the only benefit of XOR-swap by requiring a temporary register or other storage for the & results.)
This version only requires 1 AND. Also, the last two XORs are independent of each other, so total latency from inputs to both outputs is only 3 operations. (Typically 3 cycles).
For an x86 asm example, see this code-golf Exchange capitalization of two strings in 14 bytes of x86-64 machine code (with commented asm source)
Form the mask
unsigned char mask = 1u << bitPosition;
And then earn the wrath of your peer group with XOR swap algorithm.
*numbA ^= *numbB & mask;
*numbB ^= *numbA & mask;
*numbA ^= *numbB & mask;
Note this fails when numbA == numbB.
How do I set, clear, and toggle a bit?
Setting a bit
Use the bitwise OR operator (|) to set a bit.
number |= 1UL << n;
That will set the nth bit of number. n should be zero, if you want to set the 1st bit and so on upto n-1, if you want to set the nth bit.
Use 1ULL if number is wider than unsigned long; promotion of 1UL << n doesn't happen until after evaluating 1UL << n where it's undefined behaviour to shift by more than the width of a long. The same applies to all the rest of the examples.
Clearing a bit
Use the bitwise AND operator (&) to clear a bit.
number &= ~(1UL << n);
That will clear the nth bit of number. You must invert the bit string with the bitwise NOT operator (~), then AND it.
Toggling a bit
The XOR operator (^) can be used to toggle a bit.
number ^= 1UL << n;
That will toggle the nth bit of number.
Checking a bit
You didn't ask for this, but I might as well add it.
To check a bit, shift the number n to the right, then bitwise AND it:
bit = (number >> n) & 1U;
That will put the value of the nth bit of number into the variable bit.
Changing the nth bit to x
Setting the nth bit to either 1 or 0 can be achieved with the following on a 2's complement C++ implementation:
number ^= (-x ^ number) & (1UL << n);
Bit n will be set if x is 1, and cleared if x is 0. If x has some other value, you get garbage. x = !!x will booleanize it to 0 or 1.
To make this independent of 2's complement negation behaviour (where -1 has all bits set, unlike on a 1's complement or sign/magnitude C++ implementation), use unsigned negation.
number ^= (-(unsigned long)x ^ number) & (1UL << n);
or
unsigned long newbit = !!x; // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);
It's generally a good idea to use unsigned types for portable bit manipulation.
or
number = (number & ~(1UL << n)) | (x << n);
(number & ~(1UL << n)) will clear the nth bit and (x << n) will set the nth bit to x.
It's also generally a good idea to not to copy/paste code in general and so many people use preprocessor macros (like the community wiki answer further down) or some sort of encapsulation.
Using the Standard C++ Library: std::bitset<N>.
Or the Boost version: boost::dynamic_bitset.
There is no need to roll your own:
#include <bitset>
#include <iostream>
int main()
{
std::bitset<5> x;
x[1] = 1;
x[2] = 0;
// Note x[0-4] valid
std::cout << x << std::endl;
}
[Alpha:] > ./a.out
00010
The Boost version allows a runtime sized bitset compared with a standard library compile-time sized bitset.
The other option is to use bit fields:
struct bits {
unsigned int a:1;
unsigned int b:1;
unsigned int c:1;
};
struct bits mybits;
defines a 3-bit field (actually, it's three 1-bit felds). Bit operations now become a bit (haha) simpler:
To set or clear a bit:
mybits.b = 1;
mybits.c = 0;
To toggle a bit:
mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1; /* all work */
Checking a bit:
if (mybits.c) //if mybits.c is non zero the next line below will execute
This only works with fixed-size bit fields. Otherwise you have to resort to the bit-twiddling techniques described in previous posts.
I use macros defined in a header file to handle bit set and clear:
/* a=target variable, b=bit number to act upon 0-n */
#define BIT_SET(a,b) ((a) |= (1ULL<<(b)))
#define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b)))
#define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b)))
#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1
#define BITMASK_SET(x, mask) ((x) |= (mask))
#define BITMASK_CLEAR(x, mask) ((x) &= (~(mask)))
#define BITMASK_FLIP(x, mask) ((x) ^= (mask))
#define BITMASK_CHECK_ALL(x, mask) (!(~(x) & (mask)))
#define BITMASK_CHECK_ANY(x, mask) ((x) & (mask))
It is sometimes worth using an enum to name the bits:
enum ThingFlags = {
ThingMask = 0x0000,
ThingFlag0 = 1 << 0,
ThingFlag1 = 1 << 1,
ThingError = 1 << 8,
}
Then use the names later on. I.e. write
thingstate |= ThingFlag1;
thingstate &= ~ThingFlag0;
if (thing & ThingError) {...}
to set, clear and test. This way you hide the magic numbers from the rest of your code.
Other than that, I endorse Paige Ruten's solution.
From snip-c.zip's bitops.h:
/*
** Bit set, clear, and test operations
**
** public domain snippet by Bob Stout
*/
typedef enum {ERROR = -1, FALSE, TRUE} LOGICAL;
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
OK, let's analyze things...
The common expression that you seem to be having problems with in all of these is "(1L << (posn))". All this does is create a mask with a single bit on
and which will work with any integer type. The "posn" argument specifies the
position where you want the bit. If posn==0, then this expression will
evaluate to:
0000 0000 0000 0000 0000 0000 0000 0001 binary.
If posn==8, it will evaluate to:
0000 0000 0000 0000 0000 0001 0000 0000 binary.
In other words, it simply creates a field of 0's with a 1 at the specified
position. The only tricky part is in the BitClr() macro where we need to set
a single 0 bit in a field of 1's. This is accomplished by using the 1's
complement of the same expression as denoted by the tilde (~) operator.
Once the mask is created it's applied to the argument just as you suggest,
by use of the bitwise and (&), or (|), and xor (^) operators. Since the mask
is of type long, the macros will work just as well on char's, short's, int's,
or long's.
The bottom line is that this is a general solution to an entire class of
problems. It is, of course, possible and even appropriate to rewrite the
equivalent of any of these macros with explicit mask values every time you
need one, but why do it? Remember, the macro substitution occurs in the
preprocessor and so the generated code will reflect the fact that the values
are considered constant by the compiler - i.e. it's just as efficient to use
the generalized macros as to "reinvent the wheel" every time you need to do
bit manipulation.
Unconvinced? Here's some test code - I used Watcom C with full optimization
and without using _cdecl so the resulting disassembly would be as clean as
possible:
----[ TEST.C ]----------------------------------------------------------------
#define BOOL(x) (!(!(x)))
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
#define BitTst(arg,posn) BOOL((arg) & (1L << (posn)))
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
int bitmanip(int word)
{
word = BitSet(word, 2);
word = BitSet(word, 7);
word = BitClr(word, 3);
word = BitFlp(word, 9);
return word;
}
----[ TEST.OUT (disassembled) ]-----------------------------------------------
Module: C:\BINK\tst.c
Group: 'DGROUP' CONST,CONST2,_DATA,_BSS
Segment: _TEXT BYTE 00000008 bytes
0000 0c 84 bitmanip_ or al,84H ; set bits 2 and 7
0002 80 f4 02 xor ah,02H ; flip bit 9 of EAX (bit 1 of AH)
0005 24 f7 and al,0f7H
0007 c3 ret
No disassembly errors
----[ finis ]-----------------------------------------------------------------
For the beginner I would like to explain a bit more with an example:
Example:
value is 0x55;
bitnum : 3rd.
The & operator is used check the bit:
0101 0101
&
0000 1000
___________
0000 0000 (mean 0: False). It will work fine if the third bit is 1 (then the answer will be True)
Toggle or Flip:
0101 0101
^
0000 1000
___________
0101 1101 (Flip the third bit without affecting other bits)
| operator: set the bit
0101 0101
|
0000 1000
___________
0101 1101 (set the third bit without affecting other bits)
As this is tagged "embedded" I'll assume you're using a microcontroller. All of the above suggestions are valid & work (read-modify-write, unions, structs, etc.).
However, during a bout of oscilloscope-based debugging I was amazed to find that these methods have a considerable overhead in CPU cycles compared to writing a value directly to the micro's PORTnSET / PORTnCLEAR registers which makes a real difference where there are tight loops / high-frequency ISR's toggling pins.
For those unfamiliar: In my example, the micro has a general pin-state register PORTn which reflects the output pins, so doing PORTn |= BIT_TO_SET results in a read-modify-write to that register. However, the PORTnSET / PORTnCLEAR registers take a '1' to mean "please make this bit 1" (SET) or "please make this bit zero" (CLEAR) and a '0' to mean "leave the pin alone". so, you end up with two port addresses depending whether you're setting or clearing the bit (not always convenient) but a much faster reaction and smaller assembled code.
Here's my favorite bit arithmetic macro, which works for any type of unsigned integer array from unsigned char up to size_t (which is the biggest type that should be efficient to work with):
#define BITOP(a,b,op) \
((a)[(size_t)(b)/(8*sizeof *(a))] op ((size_t)1<<((size_t)(b)%(8*sizeof *(a)))))
To set a bit:
BITOP(array, bit, |=);
To clear a bit:
BITOP(array, bit, &=~);
To toggle a bit:
BITOP(array, bit, ^=);
To test a bit:
if (BITOP(array, bit, &)) ...
etc.
Let suppose few things first
num = 55 Integer to perform bitwise operations (set, get, clear, toggle).
n = 4 0 based bit position to perform bitwise operations.
How to get a bit?
To get the nth bit of num right shift num, n times. Then perform bitwise AND & with 1.
bit = (num >> n) & 1;
How it works?
0011 0111 (55 in decimal)
>> 4 (right shift 4 times)
-----------------
0000 0011
& 0000 0001 (1 in decimal)
-----------------
=> 0000 0001 (final result)
How to set a bit?
To set a particular bit of number. Left shift 1 n times. Then perform bitwise OR | operation with num.
num |= (1 << n); // Equivalent to; num = (1 << n) | num;
How it works?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
| 0011 0111 (55 in decimal)
-----------------
=> 0001 0000 (final result)
How to clear a bit?
Left shift 1, n times i.e. 1 << n.
Perform bitwise complement with the above result. So that the nth bit becomes unset and rest of bit becomes set i.e. ~ (1 << n).
Finally, perform bitwise AND & operation with the above result and num. The above three steps together can be written as num & (~ (1 << n));
num &= (~(1 << n)); // Equivalent to; num = num & (~(1 << n));
How it works?
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
~ 0001 0000
-----------------
1110 1111
& 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
How to toggle a bit?
To toggle a bit we use bitwise XOR ^ operator. Bitwise XOR operator evaluates to 1 if corresponding bit of both operands are different, otherwise evaluates to 0.
Which means to toggle a bit, we need to perform XOR operation with the bit you want to toggle and 1.
num ^= (1 << n); // Equivalent to; num = num ^ (1 << n);
How it works?
If the bit to toggle is 0 then, 0 ^ 1 => 1.
If the bit to toggle is 1 then, 1 ^ 1 => 0.
0000 0001 (1 in decimal)
<< 4 (left shift 4 times)
-----------------
0001 0000
^ 0011 0111 (55 in decimal)
-----------------
=> 0010 0111 (final result)
Recommended reading - Bitwise operator exercises
The bitfield approach has other advantages in the embedded arena. You can define a struct that maps directly onto the bits in a particular hardware register.
struct HwRegister {
unsigned int errorFlag:1; // one-bit flag field
unsigned int Mode:3; // three-bit mode field
unsigned int StatusCode:4; // four-bit status code
};
struct HwRegister CR3342_AReg;
You need to be aware of the bit packing order - I think it's MSB first, but this may be implementation-dependent. Also, verify how your compiler handlers fields crossing byte boundaries.
You can then read, write, test the individual values as before.
Check a bit at an arbitrary location in a variable of arbitrary type:
#define bit_test(x, y) ( ( ((const char*)&(x))[(y)>>3] & 0x80 >> ((y)&0x07)) >> (7-((y)&0x07) ) )
Sample usage:
int main(void)
{
unsigned char arr[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
for (int ix = 0; ix < 64; ++ix)
printf("bit %d is %d\n", ix, bit_test(arr, ix));
return 0;
}
Notes:
This is designed to be fast (given its flexibility) and non-branchy. It results in efficient SPARC machine code when compiled Sun Studio 8; I've also tested it using MSVC++ 2008 on amd64. It's possible to make similar macros for setting and clearing bits. The key difference of this solution compared with many others here is that it works for any location in pretty much any type of variable.
More general, for arbitrary sized bitmaps:
#define BITS 8
#define BIT_SET( p, n) (p[(n)/BITS] |= (0x80>>((n)%BITS)))
#define BIT_CLEAR(p, n) (p[(n)/BITS] &= ~(0x80>>((n)%BITS)))
#define BIT_ISSET(p, n) (p[(n)/BITS] & (0x80>>((n)%BITS)))
This program is to change any data bit from 0 to 1 or 1 to 0:
{
unsigned int data = 0x000000F0;
int bitpos = 4;
int bitvalue = 1;
unsigned int bit = data;
bit = (bit>>bitpos)&0x00000001;
int invbitvalue = 0x00000001&(~bitvalue);
printf("%x\n",bit);
if (bitvalue == 0)
{
if (bit == 0)
printf("%x\n", data);
else
{
data = (data^(invbitvalue<<bitpos));
printf("%x\n", data);
}
}
else
{
if (bit == 1)
printf("elseif %x\n", data);
else
{
data = (data|(bitvalue<<bitpos));
printf("else %x\n", data);
}
}
}
If you're doing a lot of bit twiddling you might want to use masks which will make the whole thing quicker. The following functions are very fast and are still flexible (they allow bit twiddling in bit maps of any size).
const unsigned char TQuickByteMask[8] =
{
0x01, 0x02, 0x04, 0x08,
0x10, 0x20, 0x40, 0x80,
};
/** Set bit in any sized bit mask.
*
* #return none
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TSetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] |= TQuickByteMask[n]; // Set bit.
}
/** Reset bit in any sized mask.
*
* #return None
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TResetBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] &= (~TQuickByteMask[n]); // Reset bit.
}
/** Toggle bit in any sized bit mask.
*
* #return none
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
void TToggleBit( short bit, unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
bitmap[x] ^= TQuickByteMask[n]; // Toggle bit.
}
/** Checks specified bit.
*
* #return 1 if bit set else 0.
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
short TIsBitSet( short bit, const unsigned char *bitmap)
{
short n, x;
x = bit / 8; // Index to byte.
n = bit % 8; // Specific bit in byte.
// Test bit (logigal AND).
if (bitmap[x] & TQuickByteMask[n])
return 1;
return 0;
}
/** Checks specified bit.
*
* #return 1 if bit reset else 0.
*
* #param bit - Bit number.
* #param bitmap - Pointer to bitmap.
*/
short TIsBitReset( short bit, const unsigned char *bitmap)
{
return TIsBitSet(bit, bitmap) ^ 1;
}
/** Count number of bits set in a bitmap.
*
* #return Number of bits set.
*
* #param bitmap - Pointer to bitmap.
* #param size - Bitmap size (in bits).
*
* #note Not very efficient in terms of execution speed. If you are doing
* some computationally intense stuff you may need a more complex
* implementation which would be faster (especially for big bitmaps).
* See (http://graphics.stanford.edu/~seander/bithacks.html).
*/
int TCountBits( const unsigned char *bitmap, int size)
{
int i, count = 0;
for (i=0; i<size; i++)
if (TIsBitSet(i, bitmap))
count++;
return count;
}
Note, to set bit 'n' in a 16 bit integer you do the following:
TSetBit( n, &my_int);
It's up to you to ensure that the bit number is within the range of the bit map that you pass. Note that for little endian processors that bytes, words, dwords, qwords, etc., map correctly to each other in memory (main reason that little endian processors are 'better' than big-endian processors, ah, I feel a flame war coming on...).
Use this:
int ToggleNthBit ( unsigned char n, int num )
{
if(num & (1 << n))
num &= ~(1 << n);
else
num |= (1 << n);
return num;
}
Expanding on the bitset answer:
#include <iostream>
#include <bitset>
#include <string>
using namespace std;
int main() {
bitset<8> byte(std::string("10010011");
// Set Bit
byte.set(3); // 10010111
// Clear Bit
byte.reset(2); // 10010101
// Toggle Bit
byte.flip(7); // 00010101
cout << byte << endl;
return 0;
}
If you want to perform this all operation with C programming in the Linux kernel then I suggest to use standard APIs of the Linux kernel.
See https://www.kernel.org/doc/htmldocs/kernel-api/ch02s03.html
set_bit Atomically set a bit in memory
clear_bit Clears a bit in memory
change_bit Toggle a bit in memory
test_and_set_bit Set a bit and return its old value
test_and_clear_bit Clear a bit and return its old value
test_and_change_bit Change a bit and return its old value
test_bit Determine whether a bit is set
Note: Here the whole operation happens in a single step. So these all are guaranteed to be atomic even on SMP computers and are useful
to keep coherence across processors.
Visual C 2010, and perhaps many other compilers, have direct support for boolean operations built in. A bit has two possible values, just like a boolean, so we can use booleans instead - even if they take up more space than a single bit in memory in this representation. This works, even the sizeof() operator works properly.
bool IsGph[256], IsNotGph[256];
// Initialize boolean array to detect printable characters
for(i=0; i<sizeof(IsGph); i++) {
IsGph[i] = isgraph((unsigned char)i);
}
So, to your question, IsGph[i] =1, or IsGph[i] =0 make setting and clearing bools easy.
To find unprintable characters:
// Initialize boolean array to detect UN-printable characters,
// then call function to toggle required bits true, while initializing a 2nd
// boolean array as the complement of the 1st.
for(i=0; i<sizeof(IsGph); i++) {
if(IsGph[i]) {
IsNotGph[i] = 0;
} else {
IsNotGph[i] = 1;
}
}
Note there is nothing "special" about this code. It treats a bit like an integer - which technically, it is. A 1 bit integer that can hold 2 values, and 2 values only.
I once used this approach to find duplicate loan records, where loan_number was the ISAM key, using the 6-digit loan number as an index into the bit array. Savagely fast, and after 8 months, proved that the mainframe system we were getting the data from was in fact malfunctioning. The simplicity of bit arrays makes confidence in their correctness very high - vs a searching approach for example.
int set_nth_bit(int num, int n){
return (num | 1 << n);
}
int clear_nth_bit(int num, int n){
return (num & ~( 1 << n));
}
int toggle_nth_bit(int num, int n){
return num ^ (1 << n);
}
int check_nth_bit(int num, int n){
return num & (1 << n);
}
Here are some macros I use:
SET_FLAG(Status, Flag) ((Status) |= (Flag))
CLEAR_FLAG(Status, Flag) ((Status) &= ~(Flag))
INVALID_FLAGS(ulFlags, ulAllowed) ((ulFlags) & ~(ulAllowed))
TEST_FLAGS(t,ulMask, ulBit) (((t)&(ulMask)) == (ulBit))
IS_FLAG_SET(t,ulMask) TEST_FLAGS(t,ulMask,ulMask)
IS_FLAG_CLEAR(t,ulMask) TEST_FLAGS(t,ulMask,0)
How do you set, clear, and toggle a single bit?
To address a common coding pitfall when attempting to form the mask:
1 is not always wide enough
What problems happen when number is a wider type than 1?
x may be too great for the shift 1 << x leading to undefined behavior (UB). Even if x is not too great, ~ may not flip enough most-significant-bits.
// assume 32 bit int/unsigned
unsigned long long number = foo();
unsigned x = 40;
number |= (1 << x); // UB
number ^= (1 << x); // UB
number &= ~(1 << x); // UB
x = 10;
number &= ~(1 << x); // Wrong mask, not wide enough
To insure 1 is wide enough:
Code could use 1ull or pedantically (uintmax_t)1 and let the compiler optimize.
number |= (1ull << x);
number |= ((uintmax_t)1 << x);
Or cast - which makes for coding/review/maintenance issues keeping the cast correct and up-to-date.
number |= (type_of_number)1 << x;
Or gently promote the 1 by forcing a math operation that is as least as wide as the type of number.
number |= (number*0 + 1) << x;
As with most bit manipulations, best to work with unsigned types rather than signed ones
This program is based out of #Jeremy's above solution. If someone wish to quickly play around.
public class BitwiseOperations {
public static void main(String args[]) {
setABit(0, 4); // set the 4th bit, 0000 -> 1000 [8]
clearABit(16, 5); // clear the 5th bit, 10000 -> 00000 [0]
toggleABit(8, 4); // toggle the 4th bit, 1000 -> 0000 [0]
checkABit(8,4); // check the 4th bit 1000 -> true
}
public static void setABit(int input, int n) {
input = input | ( 1 << n-1);
System.out.println(input);
}
public static void clearABit(int input, int n) {
input = input & ~(1 << n-1);
System.out.println(input);
}
public static void toggleABit(int input, int n) {
input = input ^ (1 << n-1);
System.out.println(input);
}
public static void checkABit(int input, int n) {
boolean isSet = ((input >> n-1) & 1) == 1;
System.out.println(isSet);
}
}
Output :
8
0
0
true
A templated version (put in a header file) with support for changing multiple bits (works on AVR microcontrollers btw):
namespace bit {
template <typename T1, typename T2>
constexpr inline T1 bitmask(T2 bit)
{return (T1)1 << bit;}
template <typename T1, typename T3, typename ...T2>
constexpr inline T1 bitmask(T3 bit, T2 ...bits)
{return ((T1)1 << bit) | bitmask<T1>(bits...);}
/** Set these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void set (T1 &variable, T2 ...bits)
{variable |= bitmask<T1>(bits...);}
/** Set only these bits (others will be cleared) */
template <typename T1, typename ...T2>
constexpr inline void setOnly (T1 &variable, T2 ...bits)
{variable = bitmask<T1>(bits...);}
/** Clear these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void clear (T1 &variable, T2 ...bits)
{variable &= ~bitmask<T1>(bits...);}
/** Flip these bits (others retain their state) */
template <typename T1, typename ...T2>
constexpr inline void flip (T1 &variable, T2 ...bits)
{variable ^= bitmask<T1>(bits...);}
/** Check if any of these bits are set */
template <typename T1, typename ...T2>
constexpr inline bool isAnySet(const T1 &variable, T2 ...bits)
{return variable & bitmask<T1>(bits...);}
/** Check if all these bits are set */
template <typename T1, typename ...T2>
constexpr inline bool isSet (const T1 &variable, T2 ...bits)
{return ((variable & bitmask<T1>(bits...)) == bitmask<T1>(bits...));}
/** Check if all these bits are not set */
template <typename T1, typename ...T2>
constexpr inline bool isNotSet (const T1 &variable, T2 ...bits)
{return ((variable & bitmask<T1>(bits...)) != bitmask<T1>(bits...));}
}
Example of use:
#include <iostream>
#include <bitset> // for console output of binary values
// and include the code above of course
using namespace std;
int main() {
uint8_t v = 0b1111'1100;
bit::set(v, 0);
cout << bitset<8>(v) << endl;
bit::clear(v, 0,1);
cout << bitset<8>(v) << endl;
bit::flip(v, 0,1);
cout << bitset<8>(v) << endl;
bit::clear(v, 0,1,2,3,4,5,6,7);
cout << bitset<8>(v) << endl;
bit::flip(v, 0,7);
cout << bitset<8>(v) << endl;
}
BTW: It turns out that constexpr and inline is not used if not sending the optimizer argument (e.g.: -O3) to the compiler. Feel free to try the code at https://godbolt.org/ and look at the ASM output.
Here is a routine in C to perform the basic bitwise operations:
#define INT_BIT (unsigned int) (sizeof(unsigned int) * 8U) //number of bits in unsigned int
int main(void)
{
unsigned int k = 5; //k is the bit position; here it is the 5th bit from the LSb (0th bit)
unsigned int regA = 0x00007C7C; //we perform bitwise operations on regA
regA |= (1U << k); //Set kth bit
regA &= ~(1U << k); //Clear kth bit
regA ^= (1U << k); //Toggle kth bit
regA = (regA << k) | regA >> (INT_BIT - k); //Rotate left by k bits
regA = (regA >> k) | regA << (INT_BIT - k); //Rotate right by k bits
return 0;
}
Setting the nth bit to x (bit value) without using -1
Sometimes when you are not sure what -1 or the like will result in, you may wish to set the nth bit without using -1:
number = (((number | (1 << n)) ^ (1 << n))) | (x << n);
Explanation: ((number | (1 << n) sets the nth bit to 1 (where | denotes bitwise OR), then with (...) ^ (1 << n) we set the nth bit to 0, and finally with (...) | x << n) we set the nth bit that was 0, to (bit value) x.
This also works in golang.
Try one of these functions in the C language to change n bit:
char bitfield;
// Start at 0th position
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}
Or
void chang_n_bit(int n, int value)
{
bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}
Or
void chang_n_bit(int n, int value)
{
if(value)
bitfield |= 1 << n;
else
bitfield &= ~0 ^ (1 << n);
}
char get_n_bit(int n)
{
return (bitfield & (1 << n)) ? 1 : 0;
}
I have a variable with "x" number of bits. How can I extract a specific group of bits and then work on them in C?
You would do this with a series of 2 bitwise logical operations.
[[Terminology MSB (msb) is the most-significant-bit; LSB (lsb) is the least-significant-bit. Assume bits are numbered from lsb==0 to some msb (e.g. 31 on a 32-bit machine). The value of the bit position i represents the coefficient of the 2^i component of the integer.]]
For example if you have int x, and you want to extract some range of bits x[msb..lsb] inclusive, for example a 4-bit field x[7..4] out of the x[31..0] bits, then:
By shifting x right by lsb bits, e.g. x >> lsb, you put the lsb bit of x in the 0th (least significant) bit of the expression, which is where it needs to be.
Now you have to mask off any remaining bits above those designated by msb. The number of such bits is msb-lsb + 1. We can form a bit mask string of '1' bits that long with the expression ~(~0 << (msb-lsb+1)). For example ~(~0 << (7-4+1)) == ~0b11111111111111111111111111110000 == 0b1111.
Putting it all together, you can extract the bit vector you want with into a new integer with this expression:
(x >> lsb) & ~(~0 << (msb-lsb+1))
For example,
int x = 0x89ABCDEF;
int msb = 7;
int lsb = 4;
int result = (x >> lsb) & ~(~0 << (msb-lsb+1));
// == 0x89ABCDE & 0xF
// == 0xE (which is x[7..4])
Make sense?
Happy hacking!
If you're dealing with a primitive then just use bitwise operations:
int bits = 0x0030;
bool third_bit = bits & 0x0004; // bits & 00000100
bool fifth_bit = bits & 0x0010; // bits & 00010000
If x can be larger than a trivial primitive but is known at compile-time then you can use std::bitset<> for the task:
#include<bitset>
#include<string>
// ...
std::bitset<512> b(std::string("001"));
b.set(2, true);
std::cout << b[1] << ' ' << b[2] << '\n';
std::bitset<32> bul(0x0010ul);
If x is not known at compile-time then you can use std::vector<unsigned char> and then use bit-manipulation at runtime. It's more work, the intent reads less obvious than with std::bitset and it's slower, but that's arguably your best option for x varying at runtime.
#include<vector>
// ...
std::vector<unsigned char> v(256);
v[2] = 1;
bool eighteenth_bit = v[2] & 0x02; // second bit of third byte
work on bits with &, |. <<, >> operators.
For example, if you have a value of 7 (integer) and you want to zero out the 2nd bit:
7 is 111
(zero-ing 2nd bit AND it with 101 (5 in decimal))
111 & 101 = 101 (5)
here's the code:
#include <stdio.h>
main ()
{
int x=7;
x= x&5;
printf("x: %d",x);
}
You can do with other operators like the OR, shift left, shift right,etc.
You can use bitfields in a union:
typedef union {
unsigned char value;
struct { unsigned b0:1,b1:1,b2:1,b3:1,b4:1,b5:1,b6:1,b7:1; } b;
struct { unsigned b0:2,b1:2,b2:2,b3:2; } b2;
struct { unsigned b0:4,b1:4; } b4;
} CharBits;
CharBits b={0},a={0};
printf("\n%d",b.value);
b.b.b0=1; printf("\n%d",b.value);
b.b.b1=1; printf("\n%d",b.value);
printf("\n%d",a.value);
a.b4.b1=15; printf("\n%d",a.value); /* <- set the highest 4-bit-group with one statement */