How do you set, clear, and toggle a single bit?
How do you set, clear, and toggle a single bit?
How do you set, clear, and toggle a bit in C/C++?
You may also be interested in checking out The Bit Twiddler, Bit Twiddling Hacks, and The Aggregate Magic Algorithms.
– anon
Jan 5 '09 at 11:13
I can easily imagine this wasn't for the question itself but for spawning a very useful reference guide. Considering I got here when I needed a bit of information, anyway.
– Joey van Hummel
Aug 11 '13 at 21:21
@glglgl /Jonathon it has enough significance for C++ to be tagged as such. It's a historic question with lots of traffic and the C++ tag will help fellow interested programmers find it through a google search.
– Luchian Grigore
Nov 4 '13 at 18:57
I'm assuming you know how to turn on/off individual bits in a byte? (E.g., using hex?)
– RastaJedi
Apr 19 '16 at 19:30
26 Answers
26
Setting a bit
Use the bitwise OR operator (|
) to set a bit.
|
number |= 1UL << n;
That will set the n
th bit of number
. n
should be zero, if you want to set the 1
st bit and so on upto n-1
, if you want to set the n
th bit.
n
number
n
1
n-1
n
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.
1ULL
number
unsigned long
1UL << n
1UL << n
long
Clearing a bit
Use the bitwise AND operator (&
) to clear a bit.
&
number &= ~(1UL << n);
That will clear the n
th bit of number
. You must invert the bit string with the bitwise NOT operator (~
), then AND it.
n
number
~
Toggling a bit
The XOR operator (^
) can be used to toggle a bit.
^
number ^= 1UL << n;
That will toggle the n
th bit of number
.
n
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 n
th bit of number
into the variable bit
.
n
number
bit
Changing the nth bit to x
Setting the n
th bit to either 1
or 0
can be achieved with the following on a 2's complement C++ implementation:
n
1
0
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.
n
x
1
x
0
x
x = !!x
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.
-1
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 n
th bit and (x << n)
will set the n
th bit to x
.
(number & ~(1UL << n))
n
(x << n)
n
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.
I would like to note that on platforms that have native support for bit set/clear (ex, AVR microcontrollers), compilers will often translate 'myByte |= (1 << x)' into the native bit set/clear instructions whenever x is a constant, ex: (1 << 5), or const unsigned x = 5.
– Aaron
Sep 17 '08 at 17:13
bit = number & (1 << x); will not put the value of bit x into bit unless bit has type _Bool (<stdbool.h>). Otherwise, bit = !!(number & (1 << x)); will..
– Chris
Nov 16 '08 at 7:49
why don't you change the last one to
bit = (number >> x) & 1
– aaronman
Jun 26 '13 at 18:47
bit = (number >> x) & 1
1
is an int
literal, which is signed. So all the operations here operate on signed numbers, which is not well defined by the standards. The standards does not guarantee two's complement or arithmetic shift so it is better to use 1U
.– Siyuan Ren
Dec 10 '13 at 8:53
1
int
1U
I prefer
number = number & ~(1 << n) | (x << n);
for Changing the n-th bit to x.– Eliko
Mar 24 '15 at 0:38
number = number & ~(1 << n) | (x << n);
Using the Standard C++ Library: std::bitset<N>
.
std::bitset<N>
Or the Boost version: boost::dynamic_bitset
.
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.
+1. Not that std::bitset is usable from "C", but as the author tagged his/her question with "C++", AFAIK, your answer is the best around here... std::vector<bool> is another way, if one knows its pros and its cons
– paercebal
Sep 19 '08 at 18:16
@andrewdotnich: vector<bool> is (unfortunately) a specialization that stores the values as bits. See gotw.ca/publications/mill09.htm for more info...
– Niklas
Dec 12 '08 at 20:40
Maybe nobody mentioned it because this was tagged embedded. In most embedded systems you avoid STL like the plague. And boost support is likely a very rare bird to spot among most embedded compilers.
– Lundin
Aug 18 '11 at 19:47
@Martin It is very true. Besides specific performance killers like STL and templates, many embedded systems even avoid the whole standard libraries entirely, because they are such a pain to verify. Most of the embedded branch is embracing standards like MISRA, that requires static code analysis tools (any software professionals should be using such tools btw, not just embedded folks). Generally people have better things to do than run static analysis through the whole standard library - if its source code is even available to them on the specific compiler.
– Lundin
Aug 19 '11 at 6:26
@Lundin: Your statements are excessively broad (thus useless to argue about). I am sure that I can find situations were they are true. This does not change my initial point. Both of these classes are perfectly fine for use in embedded systems (and I know for a fact that they are used). Your initial point about STL/Boost not being used on embedded systems is also wrong. I am sure there are systems that don't use them and even the systems that do use them they are used judiciously but saying they are not used is just not correct (because there are systems were they are used).
– Martin York
Aug 19 '11 at 6:41
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've always found using bitfields is a bad idea. You have no control over the order in which bits are allocated (from the top or the bottom), which makes it impossible to serialize the value in a stable/portable way except bit-at-a-time. It's also impossible to mix DIY bit arithmetic with bitfields, for example making a mask that tests for several bits at once. You can of course use && and hope the compiler will optimize it correctly...
– R..
Jun 28 '10 at 6:17
Bit fields are bad in so many ways, I could almost write a book about it. In fact I almost had to do that for a bit field program that needed MISRA-C compliance. MISRA-C enforces all implementation-defined behavior to be documented, so I ended up writing quite an essay about everything that can go wrong in bit fields. Bit order, endianess, padding bits, padding bytes, various other alignment issues, implicit and explicit type conversions to and from a bit field, UB if int isn't used and so on. Instead, use bitwise-operators for less bugs and portable code. Bit fields are completely redundant.
– Lundin
Aug 18 '11 at 19:19
Like most language features, bit fields can be used correctly or they can be abused. If you need to pack several small values into a single int, bit fields can be very useful. On the other hand, if you start making assumptions about how the bit fields map to the actual containing int, you're just asking for trouble.
– Ferruccio
Aug 18 '11 at 19:35
@endolith: That would not be a good idea. You could make it work, but it wouldn't necessarily be portable to a different processor, or to a different compiler or even to the next release of the same compiler.
– Ferruccio
Mar 8 '12 at 21:02
@Yasky and Ferruccio getting different answers to a sizeof() for this approach should illustrate the problems with compatibility not just across compilers but across hardware. We sometimes fool ourselves that we've solved these issues with languages or defined runtimes but it really comes down to 'will it work on my machine?'. You embedded guys have my respect (and sympathies).
– Kelly S. French
Dec 8 '16 at 16:11
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
/* x=target variable, y=mask */
#define BITMASK_SET(x,y) ((x) |= (y))
#define BITMASK_CLEAR(x,y) ((x) &= (~(y)))
#define BITMASK_FLIP(x,y) ((x) ^= (y))
#define BITMASK_CHECK_ALL(x,y) (((x) & (y)) == (y)) // warning: evaluates y twice
#define BITMASK_CHECK_ANY(x,y) ((x) & (y))
Uh I realize this is a 5 year old post but there is no argument duplication in any of those macros, Dan
– Robert Kelly
Oct 2 '13 at 14:53
BITMASK_CHECK(x,y) ((x) & (y))
must be ((x) & (y)) == (y)
otherwise it returns incorrect result on multibit mask (ex. 5
vs. 3
) /*Hello to all gravediggers :)*/– brigadir
Dec 11 '14 at 12:00
BITMASK_CHECK(x,y) ((x) & (y))
((x) & (y)) == (y)
5
3
1
should be (uintmax_t)1
or similar in case anybody tries to use these macros on a long
or larger type– M.M
Feb 6 '15 at 23:50
1
(uintmax_t)1
long
Or
1ULL
works as well as (uintmax_t)
on most implementations.– Peter Cordes
Nov 10 '17 at 21:27
1ULL
(uintmax_t)
@brigadir: depends whether you want to check for any bits set or all bits set. I updated the answer to include both with descriptive names.
– Peter Cordes
Nov 10 '17 at 21:31
It is sometimes worth using an enum
to name the bits:
enum
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 Jeremy's solution.
Alternately you could make a
clearbits()
function instead of &= ~
. Why are you using an enum for this? I thought those were for creating a bunch of unique variables with hidden arbitrary value, but you're assigning a definite value to each one. So what's the benefit vs just defining them as variables?– endolith
Dec 20 '11 at 15:09
clearbits()
&= ~
@endolith: The use of
enum
s for sets of related constants goes back a long way in c programing. I suspect that with modern compilers the only advantage over const short
or whatever is that they are explicitly grouped together. And when you want them for something other than bitmasks you get the automatic numbering. In c++ of course, they also form distinct types which gives you a little extras static error checking.– dmckee
Dec 22 '11 at 1:15
enum
const short
You'll get into undefined enum constants if you don't define a constant for each of the possible values of the bits. What's the
enum ThingFlags
value for ThingError|ThingFlag1
, for example?– Luis Colorado
Sep 30 '14 at 10:55
enum ThingFlags
ThingError|ThingFlag1
If you use this method please keep in mind that enum constants are always of signed type
int
. This can cause all manner of subtle bugs because of implicit integer promotion or bitwise operations on signed types. thingstate = ThingFlag1 >> 1
will for example invoke implementation-defined behavior. thingstate = (ThingFlag1 >> x) << y
can invoke undefined behavior. And so on. To be safe, always cast to an unsigned type.– Lundin
Dec 14 '15 at 9:25
int
thingstate = ThingFlag1 >> 1
thingstate = (ThingFlag1 >> x) << y
@Lundin: As of C++11, you can set the underlying type of an enumeration, e.g.:
enum My16Bits: unsigned short ... ;
– Aiken Drum
Mar 15 '16 at 15:01
enum My16Bits: unsigned short ... ;
/*
** 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:BINKtst.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 ]-----------------------------------------------------------------
2 things about this: (1) in perusing your macros, some may incorrectly believe that the macros actually set/clear/flip bits in the arg, however there is no assignment; (2) your test.c is not complete; I suspect if you ran more cases you'd find a problem (reader exercise)
– Dan
Oct 18 '08 at 1:51
-1 This is just weird obfuscation. Never re-invent the C language by hiding away language syntax behind macros, it is very bad practice. Then some oddities: first, 1L is signed, meaning all bit operations will be performed on a signed type. Everything passed to these macros will return as signed long. Not good. Second, this will work very inefficiently on smaller CPUs as it enforces long when the operations could have been on int level. Third, function-like macros are the root of all evil: you have no type safety whatsoever. Also, the previous comment about no assignment is very valid.
– Lundin
Aug 18 '11 at 19:14
This will fail if
arg
is long long
. 1L
needs to be the widest possible type, so (uintmax_t)1
. (You might get away with 1ull
)– M.M
Feb 6 '15 at 23:51
arg
long long
1L
(uintmax_t)1
1ull
Did you optimize for code-size? On Intel mainstream CPUs you'll get partial-register stalls when reading AX or EAX after this function returns, because it writes the 8-bit components of EAX. (It's fine on AMD CPUs, or others that don't rename partial registers separately from the full register. Haswell/Skylake don't rename AL separately, but they do rename AH.).
– Peter Cordes
Nov 10 '17 at 21:38
Use the bitwise operators: &
|
&
|
To set last bit in 000b
:
000b
foo = foo | 001b
To check last bit in foo
:
foo
if ( foo & 001b ) ....
To clear last bit in foo
:
foo
foo = foo & 110b
I used XXXb
for clarity. You'll probably be working with HEX representation, depending on the data structure in which you're packing bits.
XXXb
There is no binary notation in C. Binary integer constants is a non-standard extension.
– Lundin
Dec 14 '15 at 9:14
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)
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):
unsigned char
size_t
#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.
It's good to read but one should be aware of possible side effects. Using
BITOP(array, bit++, |=);
in a loop will most likely not do what the caller wants.– foraidt
Jul 13 '10 at 8:27
BITOP(array, bit++, |=);
Indeed. =) One variant you might prefer is to separate it into 2 macros, 1 for addressing the array element and the other for shifting the bit into place, ala
BITCELL(a,b) |= BITMASK(a,b);
(both take a
as an argument to determine the size, but the latter would never evaluate a
since it appears only in sizeof
).– R..
Jul 13 '10 at 9:19
BITCELL(a,b) |= BITMASK(a,b);
a
a
sizeof
@R.. This answer is really old, but I'd probably prefer a function to a macro in this case.
– PC Luddite
Oct 23 '15 at 17:08
Minor: the 3rd
(size_t)
cast seem to be there only to insure some unsigned math with %
. Could (unsigned)
there.– chux
Sep 27 '17 at 17:58
(size_t)
%
(unsigned)
The
(size_t)(b)/(8*sizeof *(a))
unnecessarily could narrow b
before the division. Only an issue with very large bit arrays. Still an interesting macro.– chux
Sep 27 '17 at 18:00
(size_t)(b)/(8*sizeof *(a))
b
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.
Pretty much everything about bit-fields is implementation-defined. Even if you manage to find out all details regarding how your particular compiler implements them, using them in your code will most certainly make it non-portable.
– Lundin
Aug 18 '11 at 19:50
@Lundin - True, but embedded system bit-fiddling (particularly in hardware registers, which is what my answer relates to) is never going to be usefully portable anyway.
– Roddy
Aug 19 '11 at 20:13
Not between entirely different CPUs perhaps. But you most likely want it to be portable between compilers and between different projects. And there is a lot of embedded "bit-fiddling" that isn't related to the hardware at all, such as data protocol encoding/decoding.
– Lundin
Aug 20 '11 at 9:35
...and if you get in the habit of using bit fields doing embedded programming, you'll find your X86 code runs faster, and leaner too. Not in simple benchmarks where you have the whole machine to crush the benchmark, but in real-world multi-tasking environments where programs compete for resources. Advantage CISC - whose original design goal was to make up for CPUs faster than buses and slow memory.
– user1899861
Feb 15 '13 at 22:26
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.
Micro was Coldfire MCF52259, using C in Codewarrior. Looking at the disassembler / asm is a useful exercise as it shows all the steps the CPU has to go through to do even the most basic operation. <br>We also spotted other CPU-hogging instructions in time-critical loops - constraining a variable by doing var %= max_val costs a pile of CPU cycles every time round, while doing if(var > max_val)var-=max_val uses only a couple of instructions. <br>A good guide to a few more tricks is here: codeproject.com/Articles/6154/…
– John U
Jun 19 '12 at 17:33
Even more importantly, the helper memory-mapped I/O registers provide a mechanism for atomic updates. Read/modify/write can go very badly if the sequence is interrupted.
– Ben Voigt
Feb 22 '15 at 2:16
Keep in mind that all port registers will be defined as
volatile
and therefore the compiler is unable to perform any optimizations on code involving such registers. Therefore, it is good practice to disassemble such code and see how it turned out on assembler level.– Lundin
Dec 14 '15 at 9:42
volatile
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)))
CHAR_BIT
is already defined by limits.h
, you don't need to put in your own BITS
(and in fact you make your code worse by doing so)– M.M
Feb 6 '15 at 23:52
CHAR_BIT
limits.h
BITS
#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 %dn", 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.
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("%xn",bit);
if (bitvalue == 0)
if (bit == 0)
printf("%xn", data);
else
data = (data^(invbitvalue<<bitpos));
printf("%xn", data);
else
if (bit == 1)
printf("elseif %xn", data);
else
(bitvalue<<bitpos));
printf("else %xn", 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]
/** 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...).
Don't use a table for a function that can be implemented with a single operator. TQuickByteMask[n] is equivalent to (1<<n). Also, making your arguments short is a very bad idea. The / and % will actually be a division, not bitshift/bitwise and, because signed division by a power of 2 cannot be implemented bitwise. You should make the argument type unsigned int!
– R..
Jun 28 '10 at 6:24
What's the point with this? It only makes the code slower and harder to read? I can't see a single advantage with it. 1u << n is easier to read for C programmers, and can hopefully be translated into a single clock tick CPU instruction. Your division on the other hand, will be translated to something around 10 ticks, or even as bad as up to 100 ticks, depending on how poorly the specific architecture handles division. As for the bitmap feature, it would make more sense to have a lookup table translating each bit index to a byte index, to optimize for speed.
– Lundin
Aug 18 '11 at 19:32
As for big/little endian, big endian will map integers and raw data (for example strings) in the same way: left-to-right msb to lsb throughout the whole bitmap. While little endian will map integers left to right as 7-0, 15-8, 23-18, 31-24, but raw data is still left-to-right msb to lsb. So how little endian is better for your particular algorithm is completely beyond me, it seems to be the opposite.
– Lundin
Aug 18 '11 at 19:42
@R.. A table can be useful if your plattform can't shift efficiently, like old microchip mcu's, but of course then the division in the sample is absolutly inefficient
– jeb
Nov 18 '11 at 11:28
Use this:
int ToggleNthBit ( unsigned char n, int num )
= (1 << n);
return num;
Well, it uses inefficient branching.
– asdf
Jul 2 '11 at 19:33
@asdf The compiler's job is to output the most efficient binary, the programmer's job is to write clear code
– M.M
Feb 6 '15 at 23:53
This is a good demonstration of testing, setting, and clearing a particular bit. However it's a very bad approach for toggling a bit.
– Ben Voigt
Feb 22 '15 at 2:18
Expanding on the bitset
answer:
bitset
#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 bit operations built in. Surprisingly, 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.
std::bitset is indeed implemented as bits by most compilers
– galinette
Nov 17 '14 at 20:03
@galinette, Agreed. The header file #include <bitset> is a good resource in this regard. Also, the special class vector<bool> for when you need the size of the vector to change. The C++ STL, 2nd Edition, Nicolai M. Josuttis covers them exhaustively on pgs 650 and 281 respectively. C++11 adds a few new capabilities to std::bitset, of special interest to me is a hash function in unordered containers. Thanks for the heads up! I'm going to delete my brain-cramp comment. Already enough garbage out on the web. I don't want to add to it.
– user1899861
Nov 17 '14 at 21:08
This uses at least a whole byte of storage for each
bool
. Maybe even 4 bytes for C89 setups that use int
to implement bool
– M.M
Feb 6 '15 at 23:55
bool
int
bool
@MattMcNabb, you are correct. In C++ the size of the int type necessary to implement a boolean is not specified by the standard. I realized this answer was in error some time ago, but decided to leave it here as people are apparently finding it useful. For those wanting to use bits galinette's comment is most helpful as is my bit library here ... stackoverflow.com/a/16534995/1899861
– user1899861
Feb 12 '15 at 7:23
@RocketRoy: Probably worth changing the sentence that claims this is an example of "bit operations", then.
– Ben Voigt
Feb 22 '15 at 2:20
Use one of the operators as defined here.
To set a bit, used int x = x | 0x?;
where ?
is the bit position in binary form.
int x = x | 0x?;
?
0x
is the prefix for a literal in hexadecimal, not binary.– Ben Voigt
Feb 22 '15 at 2:20
0x
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)
Variable used
int value, pos;
value - Data
pos - position of the bit that we're interested to set, clear or toggle
Set a bit
value = value | 1 << pos;
Clear a bit
value = value & ~(1 << pos);
Toggle a bit
value = value ^ 1 << pos;
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
1
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.
number
1
x
1 << x
x
~
// 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.
1ull
(uintmax_t)1
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
.
1
number
number |= (number*0 + 1) << x;
As with most bit manipulations, best to work with unsigned types rather than signed ones
Interesting look on an old question! Neither
number |= (type_of_number)1 << x;
nor number |= (number*0 + 1) << x;
appropriate to set the sign bit of a signed type... As a matter of fact, neither is number |= (1ull << x);
. Is there a portable way to do it by position?– chqrlie
Sep 27 '17 at 22:27
number |= (type_of_number)1 << x;
number |= (number*0 + 1) << x;
number |= (1ull << x);
@chqrlie IMO, the best way to avoid setting the sign bit and risking UB or IDB with shifts is to use unsigned types. Highly portable shift signed code is too convoluted to be acceptable.
– chux
Sep 27 '17 at 22:33
int set_nth_bit(int num, int n) 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);
A C++11 templated version (put in a header):
namespace bit
template <typename T1, typename T2> inline void set (T1 &variable, T2 bit) variable
template <typename T1, typename T2> inline void clear(T1 &variable, T2 bit) variable &= ~((T1)1 << bit);
template <typename T1, typename T2> inline void flip (T1 &variable, T2 bit) variable ^= ((T1)1 << bit);
template <typename T1, typename T2> inline bool test (T1 &variable, T2 bit) return variable & ((T1)1 << bit);
namespace bitmask
template <typename T1, typename T2> inline void set (T1 &variable, T2 bits) variable
template <typename T1, typename T2> inline void clear(T1 &variable, T2 bits) variable &= ~bits;
template <typename T1, typename T2> inline void flip (T1 &variable, T2 bits) variable ^= bits;
template <typename T1, typename T2> inline bool test_all(T1 &variable, T2 bits) return ((variable & bits) == bits);
template <typename T1, typename T2> inline bool test_any(T1 &variable, T2 bits) return variable & bits;
This code is broken. (Also, why do you have
;
after your function definitions?)– melpomene
Feb 10 '18 at 20:11
;
@melpomene The code is not broken, I did test it. Do you mean that it will not compile or that the result is wrong? About the extra ';' I don't remember, those can be removed indeed.
– Joakim L. Christiansen
Feb 25 '18 at 15:51
(variable & bits == bits)
?– melpomene
Feb 25 '18 at 18:25
(variable & bits == bits)
Thank you for noticing, it was supposed to be
((variable & bits) == bits)
– Joakim L. Christiansen
Feb 27 '18 at 20:56
((variable & bits) == bits)
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)
(1 << n)) & (~( (1 << n) ^ (value << n) ));
Or
void chang_n_bit(int n, int value)
bitfield = (bitfield
Or
void chang_n_bit(int n, int value)
= 1 << n;
else
bitfield &= ~0 ^ (1 << n);
char get_n_bit(int n)
return (bitfield & (1 << n)) ? 1 : 0;
value << n
may cause undefined behaviour– M.M
Feb 6 '15 at 23:57
value << n
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
read this: graphics.stanford.edu/~seander/bithacks.html and, when you'll master this, read this one: realtimecollisiondetection.net/blog/?p=78
– ugasoft
Sep 18 '08 at 16:01