How do bitwise operators work in C?
bit manipulation - Bitwise Reduction Operators in C - Stack Overflow
bit manipulation - Bitwise operation |= in C - Stack Overflow
udp - C Programming - Bitwise operators and knowing when to utilize - Stack Overflow
Videos
Hey all! I got another beginner question. So, I'm learning about bitwise operators from this site. Here's what it says about the bitwise not:
Bitwise NOT is an unary operator that flips the bits of the number i.e., if the ith bit is 0, it will change it to 1 and vice versa. Bitwise NOT is nothing but simply the oneโs complement of a number. Lets take an example.
N = 5 = (101)2
~N = ~5 = ~(101)2 = (010)2 = 2
So, ~5 = 2. Now, when I try this in C:
#include <stdio.h>
int main(void) {
int c = 5;
c = ~c;
printf("%d", c);
return 0;
}
The output of the above program is -6. What am I doing wrong?
In C, assuming unsigned or twoโs complement, !~x or ~x == 0 serves as a bitwise AND; it is 1 if and only if each bit of x is 1.
!!x or x != 0 serves as a bitwise OR; it is 1 if any bit of x is 1.
The negations, not properly called NAND or NOR since they do not apply a NAND or NOR in a bitwise fashion but rather apply a NOT to the bitwise AND or OR, are simply !!~x or ~x != 0 and !x or x == 0.
There is no bitwise XOR in the operations specified by the C standard. GCC has __builtin_parity which can provide this.
The above apply to the full width of x. Narrower widths can be implemented by setting the extra bits to identity elements (1 for AND, 0 for OR and XOR).
There are no dedicated operators for this, however in most cases you can achieve the same result using bitwise operators and casting the result to a bool, which effectively is a single bit. For example:
- AND: bitwise invert, convert to bool, negate:
bool and_reduction_4_bits(int n) { return !(~n & 0b1111); // C23 adds binary literals } - OR: just convert to bool
bool or_reduction(int n) { return n; // works for any number of bits }
The tricky one is XOR reduction. This could be done if you have a way to count the number of bits set, and then just check if that number is odd. Some compilers provide a builtin popcount() function to do that. If not, you can create your own function using bit twiddling hacks.
- XOR: count bits, check if odd
bool xor_reduction(int n) { return popcount(n) & 1; }
That's not a question, that's a whole bunch. :)
- You use bitwise operators when you want to view a number as a collection of bits, rather than an integer. It's much easier to say "I want this bit-pattern shifted two bits to the left" than to create the mathematically equivalent operation. They're conceptually different; if you think of the number as bits, using a bit-operator makes more sense.
- The
& 0xffffmakes sure the value is 16 bits, by masking off all higher bits. This assumes the system'sunsigned longis at least 16 bits wide, which is a pretty safe assumption. The&(bitwiseAND) is often used for this purpose. Look at the truth table for logical conjunction and think "false is 0, true is 1" to see how this works. - The
&before the hexadecimal constant is C's bitwise AND operator, which is used to do the masking I describe above. Basically, for single-bit variablesa & b, the result is1if and only if bothaandbare 1. The operator applies this logic to each pair of bits in its input terms. - The
~operator is C's bitwise inversion, it "flips" the bits of its argument. It is commonly used to create masks.
Everything you're talking about has to do with operations on the bit level. For example "var >> num" shifts the var to the right by num (meaning it devides the var by 2^num). Also the ~var inverts the var at bit level (eg. if var = 5 in bit notation= 101 ----> ~var = 010)