3109

How can I set, clear, and toggle a bit?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JeffV
  • 52,985
  • 32
  • 103
  • 124
  • 89
    read this: http://graphics.stanford.edu/~seander/bithacks.html and, when you'll master this, read this one: http://realtimecollisiondetection.net/blog/?p=78 – ugasoft Sep 18 '08 at 16:01
  • 22
    You may also be interested in checking out [The Bit Twiddler](http://bits.stephan-brumme.com/ "The Bit Twiddler"), [Bit Twiddling Hacks](http://graphics.stanford.edu/~seander/bithacks.html "Bit Twiddling Hacks"), and [The Aggregate Magic Algorithms](http://aggregate.org/MAGIC/ "The Aggregate Magic Algorithms"). –  Jan 05 '09 at 11:13
  • 2
    Related: *[What are bitwise shift (bit-shift) operators and how do they work?](https://stackoverflow.com/questions/141525/)* – Peter Mortensen Aug 29 '22 at 12:28
  • 2
    Some candidates: *[How to replace bits in a bitfield without affecting other bits using C](https://stackoverflow.com/q/5925755)* (2011), and *[How do you set only certain bits of a byte in C without affecting the rest?](https://stackoverflow.com/q/4439078)* (2010) – Peter Mortensen Sep 13 '22 at 09:58

27 Answers27

4312

Setting a bit

Use the bitwise OR operator (|) to set nth bit of number to 1.

// Can be whatever unsigned integer type you want, but
// it's important to use the same type everywhere to avoid
// performance issues caused by mixing integer types.
typedef unsigned long Uint;

// In C++, this can be template.
// In C11, you can make it generic with _Generic, or with macros prior to C11.
inline Uint bit_set(Uint number, Uint n) {
    return number | ((Uint)1 << n);
}

Note that it's undefined behavior to shift by more than the width of a Uint. The same applies to all remaining examples.

Clearing a bit

Use the bitwise AND operator (&) to set the nth bit of number to 0.

inline Uint bit_clear(Uint number, Uint n) {
    return number & ~((Uint)1 << n);
}

You must invert the bit string with the bitwise NOT operator (~), then AND it.

Toggling a bit

Use the bitwise XOR operator (^) to toggle the nth bit of number.

inline Uint bit_toggle(Uint number, Uint n) {
    return number ^ ((Uint)1 << n);
}

Checking a bit

You didn't ask for this, but I might as well add it.

To check a bit, shift number n to the right, then bitwise AND it:

// bool requires #include <stdbool.h> prior to C23
inline bool bit_check(Uint number, Uint n) {
    return (number >> n) & (Uint)1;
}

Changing the nth bit to x

There are alternatives with worse codegen, but the best way is to clear the bit like in bit_clear, then set the bit to value, similar to bit_set.

inline Uint bit_set_to(Uint number, Uint n, bool x) {
    return (number & ~((Uint)1 << n)) | ((Uint)x << n);
}

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.

All solutions have been tested to provide optimal codegen with GCC and clang. See https://godbolt.org/z/Wfzh8xsjW.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Paige Ruten
  • 172,675
  • 36
  • 177
  • 197
  • 163
    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
  • 55
    bit = number & (1 << x); will not put the value of bit x into bit unless bit has type _Bool (). Otherwise, bit = !!(number & (1 << x)); will.. – Chris Young Nov 16 '08 at 07:49
  • 3
    These sorts of solutions only work when the target variable is of an integral type. More general solutions can be made to work on other useful target types, such as arrays. – John Zwinck Jan 03 '09 at 22:55
  • 6
    It's just me, but I'd prefer to parenthesize the bit shift expressions (similar to what @Aaron has done above). – Happy Green Kid Naps May 09 '13 at 14:27
  • 13
    BTW the bit-fiddling here will silently fail if `number` is wider than `int` – anatolyg May 09 '13 at 15:58
  • 24
    why don't you change the last one to `bit = (number >> x) & 1` – aaronman Jun 26 '13 at 18:47
  • 1
    @Aaron: x86 has native bit test and set/clear/complement instructions too – phuclv Aug 01 '13 at 02:04
  • 2
    I think there is a problem in the notation. Say I have 0011 (decimal 3) and I want to check if **second** bit is set, e.g., the one in bold: 0 0 **1** 1. How do you refer to x? Will it be 2nd or 1st bit according to your notation, because if it is 2nd bit, I think you suggestion won't work, e.g., since you will shift 1 two times, and get 100 - which won't yield 2nd bit as I defined above. Isn't it? –  Sep 13 '13 at 21:40
  • 49
    `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 08:53
  • 9
    To clarify anatolyg's comment, the constant "1" with no modifiers is defined to be a signed int. To have this work properly for all variables, use "1ULL" instead. – JonS Jul 07 '14 at 22:46
  • 5
    @JonS for all variables up to `unsigned long long` in size anyway... there may be implementation-defined extensions such as `__int128` . To be ultra-safe `(uintmax_t)1 << x` – M.M Feb 06 '15 at 23:48
  • 70
    I prefer `number = number & ~(1 << n) | (x << n);` for Changing the n-th bit to x. – leoly Mar 24 '15 at 00:38
  • 2
    @Jiashuo Li: this statement will fail if `number` is larger than `int` and `n` is greater or equal to the number of bits in an `int`. It even invokes undefined behaviour in this case. `number = number & ~((uintmax_t)1 << n) | ((uintmax_t)x << n);` is a generic expression that should work for all sizes of `number` but may generate ugly and inefficient code for smaller sizes. – chqrlie Mar 24 '15 at 08:48
  • 2
    Related to checking a bit: Why not simply use "number & 0x01" for checking the first bit, "number & 0x08" for the fourth etc. Imho more beautiful. – Anonymous Apr 08 '15 at 11:28
  • 5
    Using operations like `-x` is not safe since the C standard allows signed integers to be (e.g.) sign-magnitude, ones' complement, or any other system that can express the necessary range, meaning that `-x` is *not* required to be the same as `(~x) + 1`. This isn't that big of a deal on modern architectures, but you never know what a sufficiently clever optimizing compiler will do with your code. – Kevin Jan 18 '16 at 18:04
  • 2
    Why do we use `~` instead `!` ? – 71GA Jan 30 '17 at 07:12
  • 1
    @Anonymous. We use masks anyway so that if we ever need to do more than one extension is obvious ? Side note, uppercase/lowercase in EBCDIC is 1 bit. – mckenzm Mar 09 '17 at 02:19
  • 1
    Doesn't the last example assume twos-complement representation? Isn't that bad / non-portable, whatever you want to call it? – Patrick Roberts Jun 14 '17 at 21:46
  • 3
    @71GA: Bitwise negation (`~`) inverts all the bits, so `~0xFFF0FFFF` is `0x000F0000`. Boolean not (`!`) gives 0 if the value is non-zero or 1 if the value is zero, so `!0xFFF0FFFF` is `0x00000000`. – Adrian McCarthy Sep 05 '17 at 20:34
  • 1
    @PatrickRoberts: Yes, it does require 2's complement. In one's complement, `-1` is `0b1111..1110`. (All-ones is `-0`). C++ also allows sign/magnitude integer representations, where `-x` just flips the sign bit. I updated this answer to point that out. It's totally fine if you are only targeting 2's complement C++ implementations. It's not UB, it's merely implementation-defined, so it is required to work correctly on implementations the define signed integers as 2's complement. I also changed the constants to `1UL`, with a note that `1ULL` may be required. – Peter Cordes Nov 10 '17 at 19:55
  • 2
    @Kevin: It is guaranteed to be safe on a C++ implementation that uses 2's complement. It's "implementation defined", not UB. The thing to worry about is portability to one's complement or sign/magnitude, not optimizing compilers. – Peter Cordes Nov 10 '17 at 19:57
  • 1
    @Peter `-x` is UB if x is INT_MIN. – Kevin Nov 10 '17 at 20:55
  • 2
    @Kevin: oh right, should be `-(unsigned long)x` which would also sidestep the signed-integer representation. (unsigned base 2 matches 2's complement semantics.) But it only works correctly if `x` is 0 or 1. Remember we're setting bit `n` to `x`. – Peter Cordes Nov 10 '17 at 21:05
  • 1
    @PeterCordes: That's entirely reasonable. But when a developer tells me "this invariant will *always* hold!" I get real nervous. – Kevin Nov 10 '17 at 21:18
  • 1
    @Kevin: I decided to leave out any mention of signed-overflow UB in my last edit, because you want to use unsigned anyway for portable `0U - 1U` -> all-ones. How does it look now? I tried to keep the answer simple. I did mention that you may need to booleanize with `!!x`. If this was my own answer, I might insert more text about always using unsigned, but I'm just maintaining this old canonical answer. (Jeremy, hope you like the changes, you might want to edit to put my changes into your own words or whatever else you want to say nearly 9 years later.) – Peter Cordes Nov 10 '17 at 21:21
  • Just noticed in the edit history that the changing `n`th bit to `x` section was added by another 3rd-party edit, and wasn't Jeremy's work in the first place. – Peter Cordes Nov 10 '17 at 21:26
  • I've run into this somewhat infrequently and always had the thought that I should come up with a single expression to do the `set bit to value` operation. Generally I do the `save state` + `unconditionally set/clear` + `restore state` in hardware. Anyway, I randomly stumbled on this and will definitely steal the expression above. – sherrellbc Jan 15 '21 at 13:46
  • `number = (number | (1UL << n)) ^ (!x << n)` Simplified to remove a logical not and a bitwise not – Shogan Aversa-Druesne Jan 18 '21 at 04:02
  • the above expression ^^^^^ allowing x to be unrestricted, x can be 0 or any positive number for true and is not tied to 0 and 1 – Shogan Aversa-Druesne Jan 18 '21 at 04:09
  • Sometimes I wonder if not a simple if/else-statement would be more efficient when changing the _n_ th bit to `x`. Would not `number = (number & ~(1UL << n)) | (x << n);` generate two bit shifts, one byte flip, one AND, one OR and lastly one assignment. While `if (x) { number |= (1 << n); } else { number &= ~(1 << n); }` would generate one "comparison", one bit shift, _either_ an OR _or_ an AND with a byte flip, as well as an assignment. 6 vs 5 operations in the worst case (clearing the bit). 6 vs 4 when setting the bit. Much more readable. But maybe some ops are more costly? – Smartskaft2 May 02 '21 at 19:08
  • 1
    @Smartskaft2 the problem is that branching with if/else may be much more expensive. Look up "branch prediction failure", or see this question: https://stackoverflow.com/q/11227809 – Angra Mainyu May 03 '21 at 11:58
  • @AngraMainyu Branch prediction errors are negligibly small: https://godbolt.org/z/vascq9Khc the if solution is even 1.2 times faster. – JulianW May 26 '21 at 15:24
  • @JulianH Thanks for testing. But in that test we have a fixed pattern of alternating true/false in the branch condition, which the branch predictor will likely predict perfectly after the first few iterations. So the test does not actually measure branch prediction failure. – Angra Mainyu May 27 '21 at 07:46
  • @AngraMainyu The CPU does not predict perfectly as you said, since there is a speedup difference between alternating and non alternating `x`, however, when randomizing the x's value, the non-`if`-solution is aobut twice as fast as the `if`-solution: https://godbolt.org/z/5aEbKchzf So, yeah you are right, branch prediction kills the performance. – JulianW May 28 '21 at 10:31
  • The best way to check a bit is `(number & (1UL << n)) != 0` (or use `!!` if you prefer) since this produces a boolean result rather than an integer (and this is usually done in boolean contexts such as if statements). While an integer expression is legal and will behave correctly in boolean contexts, depending on compiler settings it may produce a warning. Note that you need a slightly different expression to check a bitmask of multiple bits, depending on whether you're wanting to check for any bits or all bits. – Miral Oct 06 '21 at 02:17
  • The improvement suggested by @leoly is a must. I didn't see this commented, but the toggling, messes the other bits of the number as far as I can tell. Correct me If I'm wrong. – Koby 27 Jan 20 '22 at 08:26
  • @PaigeRuten I have overhauled the solution quite drastically, but I hope that I have preserved your intent. All the solutions now provide optimal codegen (tested: https://godbolt.org/z/Wfzh8xsjW). Your previous solutions had issues with sign conversion, possibly mixing integer widths, and bad codegen for setting a bit to some value. Everything is fixed and optimal now. Feel free to revert the change if you want to, but I hope that you keep it, or at least keep it in part, because it has been improved by quite a lot. – Jan Schultke Aug 30 '23 at 13:48
552

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • 42
    +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 is another way, if one knows its pros and its cons – paercebal Sep 19 '08 at 18:16
  • 1
    Nice one, Martin! You can even use an enum to 'index' the bits: enum { cEngineOn, cDoorsOpen, cAircoOn }; std::bitset< cNBBITS > mybits; mybits[ cEngineOn ].set(); const bool cbDoorOpen = mybits[ cDoorsOpen ]; ... – xtofl Sep 27 '08 at 19:21
  • among the answers here, i think this is the best way to manage bits...but I guess the spirit of the question was how to manipulate bits manually. still, +vote :) – moogs Oct 15 '08 at 11:43
  • @paercebal: vector isn't very efficient, as bool in C++ takes up a full byte of space, instead of 1 bit… – andrewdotnich Nov 13 '08 at 06:10
  • 29
    @andrewdotnich: vector is (unfortunately) a specialization that stores the values as bits. See http://www.gotw.ca/publications/mill09.htm for more info... – Niklas Dec 12 '08 at 20:40
  • 92
    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
  • 9
    @Lundin: Point one not true (some things in the STL are avoided, but a blanket statement like that is just to general, std::bitset is fine and cost nothing to use.). Point two Boost::dynamic_bitset does not depend on anything and can easily be used. – Martin York Aug 18 '11 at 19:51
  • 21
    @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 06:26
  • 47
    @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 06:41
  • @jons34yp: The SGI documentation is more conical and generally has less mistakes than cppreference. – Martin York Apr 23 '13 at 21:13
  • 1
    The topic clearly states C language, *not* C++. Clearly, this is incorrect answer, so how on earth it received 120+ upvotes?! – mloskot Sep 10 '13 at 12:24
  • 13
    @mloskot: The question clearly states C++. Its in the tag below the question what languages are valid. It got 120+ up-votes because people who can read read the question and correctly evaluated in the context of the tags. :-) Ohh. And it is simple. – Martin York Sep 10 '13 at 21:42
  • @LokiAstari I dare to claim either the tag is incorrect or the topic *and* body is impreciese. This is important issue, as it leads to SO questions become vague, thus useless really. – mloskot Sep 11 '13 at 09:14
  • All I know is that every single time I try to compile something made in C++, Boost becomes my new worst enemy. Still up-voted anyway. – sudo Aug 13 '14 at 07:14
  • 2
    @9000: Why? You should not be doing anything with boost. This is a header only library and installing boost should be package management things `sudo apt-get install boost-devel` – Martin York Aug 13 '14 at 09:09
  • The question asked for C/C++, so to be compliant with both world I think STL is not applicable here. – Luis Colorado Sep 30 '14 at 10:53
  • 2
    @LuisColorado: Yet not to talk about it would mean not having the information available for users. The point is not limit your answer but to provide a solution. The OP will decide if it is relevant by putting a tick mark by the best answer. You vote up if you think it is an answer that is useful to the community or down if it has no value to the community. – Martin York Sep 30 '14 at 14:47
  • @LuisColorado: I disagree. It solved the problem in a way that others had not mentioned. Admittedly it was for a subset of people that used C++ but the question was tagged as C++ and thus a valid answer. – Martin York Oct 02 '14 at 17:55
  • 1
    @MartinYork The embedded world is wide; but if the STL is avoided and instead some containers etc. are self-written the code is almost certainly less performant and contains more bugs. (I was working on one such system in the early 2000s. It was embedded alright, infotainment, but had the resources of a PC 5 years before.) – Peter - Reinstate Monica Jan 22 '20 at 17:15
  • 1
    This answer is featured in [Joel Spolsky's 2009 Google Tech Talk](https://www.youtube.com/watch?v=NWHfY_lvKIQ&t=17m10s), at 17 min 10 secs. – Peter Mortensen Sep 12 '21 at 21:55
283

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.

Ferruccio
  • 98,941
  • 38
  • 226
  • 299
  • 82
    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.. GitHub STOP HELPING ICE Jun 28 '10 at 06:17
  • 44
    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
  • 51
    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
  • So the bit order is arbitrary and you can't use this to twiddle individual bits in a microcontroller? – endolith Mar 08 '12 at 19:47
  • 5
    @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 08 '12 at 21:02
  • This is awesome. My question though is: after checking the `sizeof(mybits)`, I get 12 (i.e. size of three `ints`). Is this the space allocated in memory or some bug in the `sizeof` function? – Igbanam Nov 28 '12 at 22:39
  • @Yasky - what compiler are you using? I get 4 with both VC++11 and Clang 3.1. – Ferruccio Nov 29 '12 at 00:36
  • @Ferruccio I am using `gcc` version 4.4.5 – Igbanam Nov 29 '12 at 01:02
  • 1
    @R. It is possible to use both, the `struct` can be put inside a (usually anonymous) `union` with an integer etc. It works. (I realize this is an old thread btw) – Shade May 17 '14 at 04:59
  • @Shade There are no guarantees that the bit field bits map in a sane, predictable manner to the other data types in the same union. All such code will at best be completely non-portable. – Lundin Dec 14 '15 at 09:30
  • 4
    @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 08 '16 at 16:11
  • you might want `__attribute__((packed))` –  Jun 28 '20 at 00:57
249

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))
Steve Karg
  • 11
  • 1
  • 1
  • 4
  • 20
    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 02 '13 at 14:53
  • 15
    `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
  • 9
    `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 06 '15 at 23:50
  • Or `1ULL` works as well as `(uintmax_t)` on most implementations. – Peter Cordes Nov 10 '17 at 21:27
  • @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
  • 4
    `BITMASK_CHECK_ALL(x,y)` can be implemented as `!~((~(y))|(x))` – Handy999 Nov 20 '18 at 09:24
  • 5
    @Handy999 It's a bit easier to see why that works after applying De Morgan's law and re-arranging to get `!(~(x) & (y))` – Tavian Barnes Aug 13 '19 at 20:14
  • This was so extremely useful I wonder why I haven't tried this before, especially `#define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1` – William Martens Feb 16 '21 at 16:12
142

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
dmckee --- ex-moderator kitten
  • 98,632
  • 24
  • 142
  • 234
  • 2
    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
  • 5
    @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 --- ex-moderator kitten Dec 22 '11 at 01:15
  • 1
    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
  • 8
    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 09:25
  • 3
    @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
  • Why is `ThingMask` zero? – wizzwizz4 May 27 '23 at 14:14
57

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 ]-----------------------------------------------------------------

Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
yogeesh
  • 1,241
  • 8
  • 6
  • 6
    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 01:51
  • 25
    -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
  • 5
    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 06 '15 at 23:51
  • 4
    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.](https://stackoverflow.com/questions/45660139/how-exactly-do-partial-registers-on-haswell-skylake-perform-writing-al-seems-to)). – Peter Cordes Nov 10 '17 at 21:38
43

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)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
kapilddit
  • 1,729
  • 4
  • 26
  • 51
29

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.

John U
  • 2,886
  • 3
  • 27
  • 39
  • 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.
    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.
    A good guide to a few more tricks is here: http://www.codeproject.com/Articles/6154/Writing-Efficient-C-and-C-Code-Optimization
    – John U Jun 19 '12 at 17:33
  • 1
    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 02:16
  • 3
    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 09:42
  • This isn't clear. What is faster? Operating directly on the memory mapped I/O? Doing everything in (presumably) CPU registers and writing the final result to the I/O register? – Peter Mortensen Aug 22 '23 at 00:41
  • Operating directly on the I/O registers can lead to glitches (pulses) on the output pins where intermediate results of the bitwise operations are written out. – Peter Mortensen Aug 22 '23 at 00:43
29

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.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 5
    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 08:27
  • 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.. GitHub STOP HELPING ICE Jul 13 '10 at 09:19
  • 1
    @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 - Reinstate Monica Sep 27 '17 at 17:58
  • 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 - Reinstate Monica Sep 27 '17 at 18:00
29

Let’s suppose a few things first:

num = 55: An integer to perform bitwise operations (set, get, clear, and toggle).

n = 4: 0-based bit position to perform bitwise operations.

How can we get a bit?

To get the nth bit of num, right shift num, n times. Then perform a bitwise AND & with 1.

bit = (num >> n) & 1;

How does it work?

       0011 0111 (55 in decimal)
    >>         4 (right shift 4 times)
-----------------
       0000 0011
     & 0000 0001 (1 in decimal)
-----------------
    => 0000 0001 (final result)

How can we set a bit?

To set a particular bit of number, left shift 1 n times. Then perform a bitwise OR | operation with num.

num |= 1 << n;    // Equivalent to num = (1 << n) | num;

How does it work?

       0000 0001 (1 in decimal)
    <<         4 (left shift 4 times)
-----------------
       0001 0000
     | 0011 0111 (55 in decimal)
-----------------
    => 0001 0000 (final result)

How can we clear a bit?

  1. Left shift 1, n times, i.e., 1 << n.
  2. Perform a bitwise complement with the above result. So that the nth bit becomes unset and the rest of the bits become set, i.e., ~ (1 << n).
  3. Finally, perform a bitwise AND & operation with the above result and num. The above three steps together can be written as num & (~ (1 << n));

Steps to clear a bit

num &= ~(1 << n);    // Equivalent to num = num & ~(1 << n);

How does it work?

       0000 0001 (1 in decimal)
    <<         4 (left shift 4 times)
-----------------
     ~ 0001 0000
-----------------
       1110 1111
     & 0011 0111 (55 in decimal)
-----------------
    => 0010 0111 (final result)

How can we toggle a bit?

To toggle a bit, we use bitwise XOR ^ operator. Bitwise XOR operator evaluates to 1 if the corresponding bit of both operands are different. Otherwise, it evaluates to 0.

Which means to toggle a bit, we need to perform an XOR operation with the bit you want to toggle and 1.

num ^= 1 << n;    // Equivalent to num = num ^ (1 << n);

How does it work?

  • 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

user207421
  • 305,947
  • 44
  • 307
  • 483
Pankaj Prakash
  • 2,300
  • 30
  • 31
  • Thanks for the detailed explanation. Here is the link for practice problem for BIT Magic [link](https://www.geeksforgeeks.org/c-programs-gq/bit-magic-programs-gq/) – Chandra Shekhar Dec 28 '19 at 18:37
27

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.

Roddy
  • 66,617
  • 42
  • 165
  • 277
  • 3
    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
  • 1
    @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
  • 1
    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 09: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. –  Feb 15 '13 at 22:26
22

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.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
22

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)))
bill
  • 1,321
  • 11
  • 9
  • 3
    `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 06 '15 at 23:52
17

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);
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gokul Naathan
  • 171
  • 1
  • 2
16

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...).

Tim Ring
  • 1,845
  • 1
  • 20
  • 27
  • 3
    Don't use a table for a function that can be implemented with a single operator. TQuickByteMask[n] is equivalent to (1< – R.. GitHub STOP HELPING ICE Jun 28 '10 at 06:24
  • 1
    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
  • 2
    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
  • 3
    @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
13

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jeegar Patel
  • 26,264
  • 51
  • 149
  • 222
13

Use this:

int ToggleNthBit ( unsigned char n, int num )
{
    if(num & (1 << n))
        num &= ~(1 << n);
    else
        num |= (1 << n);

    return num;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 6
    Well, it uses inefficient branching. – asdf Jul 02 '11 at 19:33
  • 5
    @asdf The compiler's job is to output the most efficient binary, the programmer's job is to write clear code – M.M Feb 06 '15 at 23:53
  • 3
    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 02:18
12

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, and 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 isn't anything "special" about this code. It treats a bit like an integer—which technically, it is. A 1 bit integer that can hold two values, and two values only.

I once used this approach to find duplicate loan records, where loan_number was the ISAM key, using the six-digit loan number as an index into the bit array. It was savagely fast, and after eight 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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    std::bitset is indeed implemented as bits by most compilers – galinette Nov 17 '14 at 20:03
  • 3
    @galinette, Agreed. The header file #include is a good resource in this regard. Also, the special class vector 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. –  Nov 17 '14 at 21:08
  • 4
    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 06 '15 at 23:55
  • @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 ... http://stackoverflow.com/a/16534995/1899861 –  Feb 12 '15 at 07:23
  • 2
    @RocketRoy: Probably worth changing the sentence that claims this is an example of "bit operations", then. – Ben Voigt Feb 22 '15 at 02:20
12

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;
}
kendotwill
  • 1,892
  • 18
  • 17
8
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);
}
Felipe Augusto
  • 7,733
  • 10
  • 39
  • 73
Sazzad Hissain Khan
  • 37,929
  • 33
  • 189
  • 256
6

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

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 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
  • 1
    @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 - Reinstate Monica Sep 27 '17 at 22:33
  • 1
    It's too bad that finding this good answer requires so much scrolling! – ad absurdum Sep 13 '22 at 15:49
5

This program is based out of Jeremy's 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
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
4

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)
sam msft
  • 537
  • 6
  • 17
4

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.

3

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;   
}

lckid2004
  • 39
  • 1
-1

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 Go.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 2
    This could be much more succinctly (and likely more efficiently, unless the compiler optimizes your solution) as `(number & ~(1 << n)) | (!!x << n)`. – Will Eccles May 07 '21 at 21:16
-2

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;
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vincet
  • 47
  • 1