Bitstrings and flag shifting - arrays

I'm pretty new to bitwise and all the fun jazz and so don't quite understand everything about it. I have two questions.
A) A flags and bitshift question
I recently ran across something similar to below
if (flags & (1 << 3)) {
function_A();
}
I can see is is an AND operator and a left bit shift, however I am unsure what the flag does and its purpose (to my understanding its a collection of booleans to save space), when I usually come across left shifts, it is something such as 10100101 << 3, which would be 00101000 (I believe), but that does not seem to be the case here. So what exactly are the conditions under which the above function would be called?
B) Also a flags question (related to the first due to the nature of it).
TCPs contain packets which consist of 1 bit flags in byte 13.There is a bit of byte 13 (bit 1 i believe) which is the SYN flag to request a connection. To "request a connection" how exactly would you call that bit assuming you can access it assuming its stored in some sort of array and is accessed VIA packetNO[13]. Would it be similar to below?
if (packetNO[13] & (1 << 2)) {
}
the above checking if a connection has been requested, by shifting a true bit to position 2 (bit 1?)
Please explain these concepts to me and provide examples to assist if possible, I am unsure if I am correct or not.

The and operator is such its output is at one only if both operands are at 1.
Hence
if(f & 1) { ... }
tests is the least significant bit of f is set.
If you want to test if another bit is set, there are two ways to do that.
use the bitwise shift operator << that will shift its operand by a given amount. For instance, to test if the third bit (or bit #2 counting from lsb) is set, you an use 1<<2. This will result to a number equal to 000..00100 and by anding, this will check if the corresponding bit is set.
if(f & (0x1<<2)) { ... }
Alternatively, you can use hexadecimal numbers do describe the bit pattern that you want to test.
The same test can done by using 0x4 as the binary code of 4 is 000..0100
if(f & 0x4) { ... }
It is up to you to determine which one is more readable.
So, the first test in your question checks if fourth bit of flag (bit #3) is set and the second one tests if bit #1 of packect[13] is set.

Related

Is there a better way to define a preprocessor macro for doing bit manipulation?

Take macro:
GPIOxMODE(gpio,mode,port) ( GPIO##gpio->MODER = ((GPIO##gpio->MODER & ~((uint32_t)GPIO2BITMASK << (port*2))) | (mode << (port * 2))) )
Assuming that the reset value of the register is 0xFFFF.FFFF, I want to set a 2 bit width to an arbitrary value. This was written for an STM32
MCU that has 15 pins per port. GPIO2BITMASK is defined as 0x3. Is there a better way for clearing and setting a random 2 bits in anywhere in the
32-bit wide register.
Valid range for port 0 - 15
Valid range for mode 0 - 3
The method I came up with is to bit shift the mask, invert it, logically AND it with the existing register value, logically OR the result with a bit shifted new value.
I am looking to combine the mask and new value to reduce the number of logical operations bit shift operations. The goal is also keep the process generic enough so that I can use for bit operations of 1,2,3 or 4 bit widths.
Is there a better way?
In the long and sort of it, is there a better way is really an opened question. I am looking specifically for a method that will reduce the number of logical operations and bit shift operations, while being a simple one lined statement.
The answer is NO.
You MUST do reset/set to ensure that the bit field you are writing to has the desired value.
The answers received can be better (in a matter of opinion/preference/philosophy/practice) in that they aren't necessary a macros and have have parameter checking. Also pit falls of this style have been pointed out in both the comments and responses.
This kind of macros should be avoided as a plaque for many reasons:
They are not debuggable
They are hard to find error prone
and many other reasons
The same result you can archive using inline functions. The resulting code will be the same effective
static inline __attribute__((always_inline)) void GPIOMODE(GPIO_TypeDef *gpio, unsigned mode, unsigned pin)
{
gpio -> MODER &= ~(GPIO_MODER_MODE0_Msk << (pin * 2));
gpio -> MODER |= mode << (pin * 2);
}
but if you love macros
#define GPIOxMODE(gpio,mode,port) {volatile uint32_t *mdr = &GPIO##gpio->MODER; *mdr &= ~(GPIO_MODER_MODE0_Msk << (port*2)); *mdr |= mode << (port * 2);}
I am looking to combine the mask and new value to reduce the number of
logical operations bit shift operations.
you cant. You need to reset and then set the bits.
The method I came up with is to bit shift the mask, invert it,
logically AND it with the existing register value, logically OR the
result with a bit shifted new value.
That or an equivalent is the way to do it.
I am looking to combine the mask and new value to reduce the number of
logical operations bit shift operations. The goal is also keep the
process generic enough so that I can use for bit operations of 1,2,3
or 4 bit widths.
Is there a better way?
You must accomplish two basic objectives:
ensure that the bits that should be off in the affected range are in fact off, and
ensure that the bits that should be on in the affected range are in fact on.
In the general case, those require two separate operations: a bitwise AND to force bits off, and a bitwise OR (or XOR, if the bits are first cleared) to turn the wanted bits on. There may be ways to shortcut for specific cases of original and target values, but if you want something general-purpose, as you say, then your options are limited.
Personally, though, I think I would be inclined to build it from multiple pieces, separating the GPIO selection from the actual computation. At minimum, you can separate out a generic macro for setting a range of bits:
#define SETBITS32(x,bits,offset,mask) ((((uint32_t)(x)) & ~(((uint32_t)(mask)) << (offset))) | (((uint32_t)(bits)) << (offset)))
#define GPIOxMODE(gpio,mode,port) (GPIO##gpio->MODER = SETBITS32(GPIO##gpio->MODER, mode, port * 2, GPIO2BITMASK)
But do note that there appears to be no good way to avoid such a macro evaluating some of its arguments more than once. It might therefore be safer to write SETBITS32 as a function instead. The compiler will probably inline such a function in any case, but you can maximize the likelihood of that by declaring it static and inline:
static inline uint32_t SETBITS32(uint32_t x, uint32_t bits, unsigned offset, uint32_t mask) {
return x & ~(mask << offset) | (bits << offset);
}
That's easier to read, too, though it, like the macro, does assume that bits has no set bits outside the mask region.
Of course there are other, similar formulations. For instance, if you do not need to support discontinuous bit ranges, you might specify a bit count instead of a bit mask. This alternative does that, protects against the user providing bits outside the specified range, and also has some parameter validation:
static inline uint32_t set_bitrange_32(uint32_t x, uint32_t bits, unsigned width,
unsigned offset) {
if (width + offset > 32) {
// error: invalid parameters
return x;
} else if (width == 0) {
return x;
}
uint32_t mask = ~(uint32_t)0 >> (32 - width);
return x & ~(mask << offset) | ((bits & mask) << offset);
}

bitwise operation confusion in tutorials

how is:
GIMSK |= (1 << PCIE);
PCMSK |= (1 << PCINT4);
equal to (I can use the above or the below in my setup of my program, both work and activate pin 4), the GIMSK and the PCMSK are for some reason equal to each other, I am trying to learn why.
GIMSK = 0b00100000;
PCMSK = 0b00010000;
first:
https://thewanderingengineer.com/2014/08/11/pin-change-interrupts-on-attiny85/
second:
https://embeddedthoughts.com/2016/06/06/attiny85-introduction-to-pin-change-and-timer-interrupts/
data:
http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-2586-AVR-8-bit-Microcontroller-ATtiny25-ATtiny45-ATtiny85_Datasheet.pdf
The sheet says PCIE is 0b00100000 in the bit mask, so somehow |= (1 << PCIE) equals that? I don't get it if PCIE is supposed to be that, doing a shift would change that value..
how and why would you use that instead of binary? I would guess it changes it but obviously, somehow it doesn't. I've asked this on several different places nobody has an answer so I came here. Hopefully someone can explain.
I'm new to C, I just learned bitwise operations today to try to figure out what is going on here, my code does work with either or but I want to know why! Thanks.
It is equal because all other bits of those registers were 0 before the OR operation
1u << x shifts one by x positions left. As a result you have the number with all bits except x cleared
Short Version
Break apart the compound expression from x |= y to x = x | y
Load integer '1' which is just binary `[0000 0001] and shift it to the spot we want.
Variable is defined in a header, or elsewhere which says where that bit is for compatibility. New card? Just get a new definition file- this is done automatically- usually). PCIE and PCINT4 are defined somewhere, look for it if needed, but this is supposed to handle those details for you.
Yet- we know is PCINT4 is 4 and PCIE is 5 respectively because of the second set- where we see a shifted '1'- 5 spaces for PCIE and 4 spaces for PCINT4. That's why they seem equivalent. Because they are literally equivalent- once you evaluate the expression you know that 0b means that what follows is binary (which might have been obvious). But they are NOT equivalent. Not exactly- see below--
4-So if you "OR" a register, it overrides whatever is there if TRUE and forces it to be what True and leaves everything else alone. We shift that 1 to show the bit we want, then we choose the operant that will have the effect we want. Look at the table for others.**
But we get GIMSK = GIMSK OR 0b00100000 and PCMSK = PCMSK OR 0b00010000;
Which is similar, but not exactly the same thing.
The devil is in the details, see below for
Detailed Explanation.
AKA someone better read this, took me forever.
GIMSK |= (1 << PCIE);
PCMSK |= (1 << PCINT4);
equal to (I can use the above or the below in my setup of my program, both work and activate pin 4), the
GIMSK and the PCMSK are for some reason equal to each other, I am
trying to learn why.
GIMSK = 0b00100000;
PCMSK = 0b00010000;
Let's take it lexicographically by the token to start, so we are all talking about the same thing.
GIMSK |= (1 << PCIE);
Starting at the first bit. Pick it apart-
GIMSK- variable or 'id'
|= - operator and assignment combo bitwise OR and =
1 - the integer 1
<< - shift operation
PCIE - Variable and ID
Of course, this makes it harder to explain. What is |=? I'm certain that led to confusion on this question for some. The better-known one is +=. So if I have a variable x, and I always add to itself, really any time you are counting, etc. the variable is on both sides of the equation. Like this:
x = x + 1 ;this is so common though, that in C, it was shortened to +=
x += 1 ; now its written like this. It takes some time
so programmers are lazy, and if something 'cool' pops up in one language, it usually spreads to the others, so most languages allow this now. It does make a difference if you write += or =+, at least in Java. Won't hit that though.
y = y * 2; it works for other types of operands
y *= 2; Now we take y, multiply by 2 and assign back to y.
Now, let's look at 'C' style bitwise operators- most languages have adopted similar notation though there are exceptions.
Usually in C you use two symbols to compare '&&" or '||' or '=='
Well, that's because the single operator compares bits. This got one symbol because it's much more natural on a computer and much more common. Not to us anymore, we are abstracted away from it by layers of software.
So we have: ** Good Source for more info
Bitwise AND (&)
Bitwise OR (|)
Bitwise XOR (^)
Bitwise NOT (~)
And we can also make this compond (Click for more info)
Basically, they compare some variable on the right with the left and assign it back to the right. Like this x = x* y => x *= y.
Likewise we have x &= y, x |= y and, x ^= y
So for the above- let's unwrap it first- write it out longhand to make it easier to understand-
GIMSK |= (1 << PCIE)
GIMSK = GIMSK | (1 << PCIE) #OK! much easier to understand if your new.
#NOW we can lexigraphically analyze this
VarA {assignment} VarA OR ( 1 {Operator} VarB )
#Ignore the assignment side, for now, practice order of Operations
#Start with Parenthetical Exp.
1 {Operator} VarB
#It turns out this is defined.
#OP Didnt know but computer does. = 5 in this case.
#so 1, shift left 5. To bitwise shift, need bits
1 => 0b00000001 << 5 = 0b00100000
# shift left is really multiplied by 2 in base 10, divide by 2 in shift right. Beware Right Shift, esp in float.
So now we have: GIMSK = GIMSK OR 0b00100000
GIMSK |= (1 << PCIE); PCMSK |= (1 << PCINT4);
GIMSK = 0b00100000; PCMSK = 0b00010000;
Which is just what you already said. More or less. The 2nd operations are not equivalent though as I mentioned above in the short answer. Thats covered at the end.
This is Assembly format, GIMSK is an 8-bit register. We created a bitmask, by moving a 1 to the register we want to effect, and putting a 0 in the bits we want to leave alone. The |= means we will compare the two the save it back to the same register. That's it. OR 1 will always turn it on. Which is what we want.
Think about what we want to do to start. We want to set a boolean value to HIGH or TRUE, or 1, however, you put it. We say "Lets set the register bit that we specify if your value (0/1) OR my value (1) is 1." Well, we know our value is 1 because that's what we put. So when you bit-wise OR (is that a verb?), you are writing a value on the basis of one of 2 values being a 1. It either writes a one or leaves a one, unless you send 0 and it sends 0 it stays off.
It says "I think this should be on. If any other process thinks this should be on, leave it even if I don't need it so (it sends a 0)" It's worth thinking through on paper, and thinking through each of the operands. Make a colored table, that's how I got to understand them. Not of the operands will flip the values whatever it is. AND checks the value for you, it leaves the register the same- Operating on each reg will have this effect. I used to have a cheat sheet, I would have loved to include, but I lost it- but it summarized for my dumb brain the behavior of each operand.
REMEMBER- we can not operate on a single bit. This is a critical bit you need to understand. You cant change just one bit. If I have 0010 0010 and I want to say, hey computer, change byte 6. You cant! You have to load the whole word or byte into a register or at least half (16bits in MIPS, 8 in ATMEL 16bit controllers**), and operate on the whole thing. You can't operate directly from memory (Ram, SSD, L2 Cache- way too far away). There's no such thing as popping a single bit into a register to change it, though there are tricks to make new bytes (8bit) in the shape you want. Want just the 6th bit, well {0100 000} -with AND, will get it for you. Then you can shift right, or divide by 2^6, etc. We will get back to this. First- the actions of the Comparators if you care to learn more:
*this chip is 8 bit. Doubt they have half read. Bit
Logical Operators v. Registers
Register(b) Me OR NOR XOR AND NAND N XNOR
1 0 1 0 1 0 1 0 0
0 0 0 1 0 0 1 1 1
1 1 1 0 0 1 0 0 1
0 1 1 0 1 0 1 1 0
So the above looks at the single bit we want to effect. The left 2 columns are all possible scenarios (just 4), where we show the bit of the register in that byte. I keep saying byte. A register is, as I mentioned 16 or 32 bits usually, so I really mean Word. I have just organized this example around a hypothetical 8 bit machine. edit- this is an 8 bit chip, 32 registers. one of which is this one
Now! What do we want to do? We Want to change 1 byte, which represents a boolean value, but we don't want to mess with the rest! If you OR across all 8 bytes- do this on paper- it leaves the values in there already alone. Perfect! That's what we want.
Whatever they are set to, they stay, if it's 1, OR leaves it a 1, if it's 0, it stays.
Ah, I should mention why.
Its because you start with 0000 0001 (1) so everything is 0, except the 1st bit. Why did we start with 0000 0001? because you told it to.
See here syntax Arduino Doc Bitwise Ops
So, without reviewing Binary, 1 in binary is 0000 0001 It should be noted, that in a computer, it can't tell that 11001100 isn't 11,001,100 (eleven million), or if its 204 (binary) or even 285,217,024 (if it was HEX), or 2,359,872 (in Octal).
The compiler and computer 'know' we always think base 10, but the computer never does, just base 2 or compressed for easy human reading, into octal (2^2,) or hex (2^4) eg, each 'character' is 2 bits or 4 bits. 0x0A is 0b1010. And right there is where I am getting at. We indicate the values are not base 10, with a prefix. 0b***** is binary. 0x**** is hex. And I can never remember Octal- no one uses it anyway.
So!
see here if needed: Another practical book I wrote on Bitwise Ops, that covers basic Binary a little.
Then you shift that bit by the PIN NUMBER I don't know the right term, and this is certainly not it, but you say the register you want to effect is the 5th register. Ok.
#take a 1,
0000 0001 = $temp
#shift it 5 spots "<<" , where 5 is the PCIE 'bit' value spot number.
1<<5 = 32
#binary equals 32.
You could replace either GIMSK value with 32 and it would be fine, again equivalent, or 0x020
# 0010 0000
# Then OR this with whats in the register now:
1010 1010 (made up number, a mix of ones and 0s)
0010 0000 (Our Value)
OR=>
1010 1010 Result.
Note how we left the other bits alone, and only changed what we wanted! Effective bit mask!
Now, why does it say PCIE, and whatever the other one is. Its because somewhere, when you compile, there is a file that assigns values to those variables. This allows the code to be compatible across several different chip designs. The ATMEGA and the ATTINY do not have the same interrupt pin. Though it likely goes to the same internal register.
#Take it bit by bit, no Pun intended
GIMSK |= (1 << PCIE);
PCMSK |= (1 << PCINT4);
GIMSK = 0b00100000;
PCMSK = 0b00010000;
Again, starting at the first bit from above.
GIMSK- some variable
|= - bitwise OR
1 - the integer 1
`<`< - shift operation
PCIE - another var
So all you are doing is taking a base 10 integer- 1, which we know equals 0b0000 0001, then we are pushing that 1 (now in binary to the spot indicated by PCIE or PCINT4. So the latter 2 are just simply variables that hold the bit number, so if it changes, the code doesn't break.
From the latter 2 lines, we infer that PCIE is 5 and PCINT4 is 4. GIMSK is now equal to 32 and the other 16. Shifting << and >> has the effect of multiplying or diving by 2. Although, shifting down is risky for reasons I won't get into, but if you need to multiply a number by 2, for a computer, it's much faster to shift left by 1 bit than it is to go through the multiplayer.
We talked about the OR already. It sets a 1, if there's not one, otherwise it leaves the other bits alone because they are 0.
Equivalent or Not??
GIMSK |= (1 << PCIE);
GIMSK = 0b00100000;
GIMSK = GIMSK OR 0b00100000
PCMSK |= (1 << PCINT4);
PCMSK = 0b00010000;
PCMSK = PCMSK OR 0b00010000
So evaluating the 1st expression in each set gets the 3rd equation. But notice they look a little different. They are not equivalent statements, though, as you say they may work. It depends on what those other bits are.
PCMSK = 0b00010000; #This sets the PCMSK register to be exactly
=> PCMSK = `0|0|0|1|0|0|0|0
#While
PCMSK = PCMSK OR 0b00010000; # yields PCMSK = `?|?|?|1|?|?|?|?`
#Obviously,
GIMSK = 0b00001000; # This sets the GIMSK register to be exactly
=> GIMSK = `0|0|0|0|1|0|0|0`
While`GIMSK = GIMSK OR 0b00001000; # yields
GIMSK = ` ?|?|?|?|1|?|?|? `
while the OR statement leaves the other bits alone, if they were set by something else, and just changes the 5 (or 4th bit) as the case my be. The OR statement is probably the better statement. If you found the latter statement suggested in a reputable place though, it's probably fine.
Conclusion
So that's it. It's much easier than you thought probably now that the different bits make sense. I wrote this though with the hope it'll give some lasting insight rather than just a quick answer. Although in truth- it was complicated. There are a LOT of computer science concepts buried in those 2 statements, that if you're not in the know, might as well be hieroglyphics.
All this makes much more sense if you dive into how a computer works.
Check out Chapter 2 and 3 of Computer Organization and Design (5th ed) Patterson and Hennesy. It's the standard. If this is for fun, you can skim it. But the computer has Registered, of a defined width- 8, 16, 32. and 64 or even 128 (rarely e.g. x86 AVX- Intel x86). but usually 32 bit. These are the bits of data in hand, what the processor actually touches. The processor can only operate on registers. So everything, under the hood, will end up back there.
Now using interrupts correctly is a whole other topic. I again recommend the same book- Ch 5 and Appendix A7
Note- My assembly class was in MIPS. I've never specifically studied this microcontroller. If I get some of the architecture wrong, forgive me.

Bit setting logic in C

I'm having a hard time understanding the logic behind successfully setting a bit in a 32 bit register. Here is the pseudo-code for the function:
Read the master register,
If the 29th bit CREG_CLK_CTRL_I2C0 is not set, set it
uint32_t creg;
//read the CREG Master register
creg = READ_ARC_REG((volatile uint32_t)AR_IO_CREG_MST0_CTRL);
if((creg & (1 << CREG_CLK_CTRL_I2C0)) == 0){
creg |= ( 1 << CREG_CLK_CTRL_I2C0);
WRITE_ARC_REG(creg, (volatile uint32_t)(AR_IO_CREG_MST0_CTRL));
}
If the CREG master register is initially empty, the logic doesn't work as intended. However, if I fill it with all zeros and a 1 in the 31st bit (1000...0) the logic does work. I'm not sure if my test condition is incorrect or if it could be something else.
Can anyone help?
Personally, I would use the data type given: uint32_t. That will guarantee alignment regardless of context. That is (factored for clarity, and assuming shift doesn't yield different size-type):
uint32_t mask = ((uint32_t)1) << CREG_CLK_CTRL_I2C0;
if((creg & mask) == 0){
creg |= mask;
WRITE_ARC_REG(creg, (volatile uint32_t)(AR_IO_CREG_MST0_CTRL));
}
Here are a few ideas towards debugging your issue:
Step 1: Make sure you actually understand how that register works. Remember, microcontroller registers may behave differently from memory. The register may ignore your attempt to write a 1 to a bit until after some other condition is met. Perhaps that's why it works if you write a 1 to bit 31 first. What does bit 31 do?
Step 2: I poked around online and found that the same header that defines READ_ARC_REG() and WRITE_ARC_REG() may also include the definition for SET_ARC_BIT(). See if you can find and use that.
Step 3: Make sure what you're trying to write makes sense. Step through the function in your debugger and/or add some form of printout to display the value you're attempting to write to the register. Then read the register after doing so and repeat that process. See if you tried to write the correct value, then see whether that write actually took. If your code tried to write your desired value to the register but the subsequent read showed that your write didn't change the bit then go back to Step 1 above.
Just a guess (I don't do much embedded programming), but according to C standard the number literal 1 has type int. In embedded programming int can be 16 bits, in which case your left shift will have undefined behaviour, since right operand is too large.
So try using 1L to make this of type long.
Also, as mentioned by Olaf in comments, do not use (volatile uint32_t) cast unless you are sure that you need it. Some googling suggests that this is about Arduino 101, and source code I found does use both READ_ARC_REG and WRITE_ARC_REG without any cast.
creg = READ_ARC_REG(AR_IO_CREG_MST0_CTRL);
if((creg & (1L << CREG_CLK_CTRL_I2C0)) == 0){
creg |= (1L << CREG_CLK_CTRL_I2C0);
WRITE_ARC_REG(creg, AR_IO_CREG_MST0_CTRL);
}

Applications of bitwise operators in C and their efficiency? [duplicate]

This question already has answers here:
Real world use cases of bitwise operators [closed]
(41 answers)
Closed 6 years ago.
I am new to bitwise operators.
I understand how the logic functions work to get the final result. For example, when you bitwise AND two numbers, the final result is going to be the AND of those two numbers (1 & 0 = 0; 1 & 1 = 1; 0 & 0 = 0). Same with OR, XOR, and NOT.
What I don't understand is their application. I tried looking everywhere and most of them just explain how bitwise operations work. Of all the bitwise operators I only understand the application of shift operators (multiplication and division). I also came across masking. I understand that masking is done using bitwise AND but what exactly is its purpose and where and how can I use it?
Can you elaborate on how I can use masking? Are there similar uses for OR and XOR?
The low-level use case for the bitwise operators is to perform base 2 math. There is the well known trick to test if a number is a power of 2:
if ((x & (x - 1)) == 0) {
printf("%d is a power of 2\n", x);
}
But, it can also serve a higher level function: set manipulation. You can think of a collection of bits as a set. To explain, let each bit in a byte to represent 8 distinct items, say the planets in our solar system (Pluto is no longer considered a planet, so 8 bits are enough!):
#define Mercury (1 << 0)
#define Venus (1 << 1)
#define Earth (1 << 2)
#define Mars (1 << 3)
#define Jupiter (1 << 4)
#define Saturn (1 << 5)
#define Uranus (1 << 6)
#define Neptune (1 << 7)
Then, we can form a collection of planets (a subset) like using |:
unsigned char Giants = (Jupiter|Saturn|Uranus|Neptune);
unsigned char Visited = (Venus|Earth|Mars);
unsigned char BeyondTheBelt = (Jupiter|Saturn|Uranus|Neptune);
unsigned char All = (Mercury|Venus|Earth|Mars|Jupiter|Saturn|Uranus|Neptune);
Now, you can use a & to test if two sets have an intersection:
if (Visited & Giants) {
puts("we might be giants");
}
The ^ operation is often used to see what is different between two sets (the union of the sets minus their intersection):
if (Giants ^ BeyondTheBelt) {
puts("there are non-giants out there");
}
So, think of | as union, & as intersection, and ^ as union minus the intersection.
Once you buy into the idea of bits representing a set, then the bitwise operations are naturally there to help manipulate those sets.
One application of bitwise ANDs is checking if a single bit is set in a byte. This is useful in networked communication, where protocol headers attempt to pack as much information into the smallest area as is possible in an effort to reduce overhead.
For example, the IPv4 header utilizes the first 3 bits of the 6th byte to tell whether the given IP packet can be fragmented, and if so whether to expect more fragments of the given packet to follow. If these fields were the size of ints (1 byte) instead, each IP packet would be 21 bits larger than necessary. This translates to a huge amount of unnecessary data through the internet every day.
To retrieve these 3 bits, a bitwise AND could be used along side a bit mask to determine if they are set.
char mymask = 0x80;
if(mymask & (ipheader + 48) == mymask)
//the second bit of the 6th byte of the ip header is set
Small sets, as has been mentioned. You can do a surprisingly large number of operations quickly, intersection and union and (symmetric) difference are obviously trivial, but for example you can also efficiently:
get the lowest item in the set with x & -x
remove the lowest item from the set with x & (x - 1)
add all items smaller than the smallest present item
add all items higher than the smallest present item
calculate their cardinality (though the algorithm is nontrivial)
permute the set in some ways, that is, change the indexes of the items (not all permutations are equally efficient)
calculate the lexicographically next set that contains as many items (Gosper's Hack)
1 and 2 and their variations can be used to build efficient graph algorithms on small graphs, for example see algorithm R in The Art of Computer Programming 4A.
Other applications of bitwise operations include, but are not limited to,
Bitboards, important in many board games. Chess without bitboards is like Christmas without Santa. Not only is it a space-efficient representation, you can do non-trivial computations directly with the bitboard (see Hyperbola Quintessence)
sideways heaps, and their application in finding the Nearest Common Ancestor and computing Range Minimum Queries.
efficient cycle-detection (Gosper's Loop Detection, found in HAKMEM)
adding offsets to Z-curve addresses without deconstructing and reconstructing them (see Tesseral Arithmetic)
These uses are more powerful, but also advanced, rare, and very specific. They show, however, that bitwise operations are not just a cute toy left over from the old low-level days.
Example 1
If you have 10 booleans that "work together" you can do simplify your code a lot.
int B1 = 0x01;
int B2 = 0x02;
int B10 = 0x0A;
int someValue = get_a_value_from_somewhere();
if (someValue & (B1 + B10)) {
// B1 and B10 are set
}
Example 2
Interfacing with hardware. An address on the hardware may need bit level access to control the interface. e.g. an overflow bit on a buffer or a status byte that can tell you the status of 8 different things. Using bit masking you can get down the the actual bit of info you need.
if (register & 0x80) {
// top bit in the byte is set which may have special meaning.
}
This is really just a specialized case of example 1.
Bitwise operators are particularly useful in systems with limited resources as each bit can encode a boolean. Using many chars for flags is wasteful as each takes one byte of space (when they could be storing 8 flags each).
Commonly microcontrollers have C interfaces for their IO ports in which each bit controls 1 of 8 ports. Without bitwise operators these would be quite difficult to control.
Regarding masking, it is common to use both & and |:
x & 0x0F //ensures the 4 high bits are 0
x | 0x0F //ensures the 4 low bits are 1
In microcontroller applications, you can utilize bitwise to switch between ports. In the below picture, if we would like to turn on a single port while turning off the rest, then the following code can be used.
void main()
{
unsigned char ON = 1;
TRISB=0;
PORTB=0;
while(1){
PORTB = ON;
delay_ms(200);
ON = ON << 1;
if(ON == 0) ON=1;
}
}

Help to begin in assigning specific bits

So I have a problem for my class that I am having trouble getting started on. I am not asking people to do the problem for me, I just would like any nudge in the right direction. I need to create a function in C that when given any 32 bit integer it returns an integer where every 4th bit is set to a 1 starting at the least sig bit. I understand what it is supposed to look like in the end, but getting started I am lost on. We are not allowed to use any for loops or conditionals, just the standard bitwise and logical operators(! ~ & ^ | + << >>). Once again, I am not asking anyone to do this for me, I just would like some help in getting me thinking on the right track. I have seen some of the other posts on here and on other pages, but none seem to click. I understand that you can bitshift a 1 into a certain place x<<3 but going beyond that I am stuck. Any help would be appreciated.
int get_int_with_every_fourth_bit_set()
{
return 0x88888888;
}
Ok, that was mostly facetious. Here's a list of what the bitwise operators do:
bitwise NOT (~): Toggle a bit, 0 to 1 and 1 to 0
AND (&): Set a bit if the bit in that position is set in both operands
OR (|): Set a bit if the bit in that position is set in either operand
XOR (^): Set a bit if exactly one bit in that position is set between the two operands
Bitwise shift (<< and >>): Move each bit over the specified amount in the given direction. When shifting left, zeros are added to the least significant bit. When shifting right, a zero will be added if the value is either unsigned or positive.
Here are some bitwise tricks that are good to know:
A bitwise shift left by one is the same as multiplying by two. A bitwise shift right by one is the same as dividing by two, and rounding down.
All powers of two have exactly one 1 bit. To see if a number is a power of two, you can do this:
return !(x & (x - 1)) && x
As an example, say x = 16, which is a power of two. Then, x - 1 = 15, so the values to be ANDed are 00010000 and 00001111. Since each bit position has a zero in at least one of the two operands, the result is zero. !0 is true, so check to see if x != 0. Since 16 != 0, the statement returns true. If you try it with a number that is not a power of two and not zero, then the x & (x - 1) check will always be true. So cool!
Another tip: since 0 ^ 0 = 0 and 1 ^ 1 = 0, you can use XOR to see what bits have changes. For example, if you have two bytes and want to see the bits that changed between then, the XOR of the two bytes will give you a 1 in the position of all bits that have changed.
Can you write down (in hex) the 32 bit integer that has every 4th bit set to 1, and all other bits set to 0?
Now, is there an operation you can apply to your input and this magic number, which sets every 4th bit of the input to 1, but leaves the other bits alone?
Check out bitmasking.
...Therefore, to make sure a bit is on, OR can be used with a 1. To leave a bit unchanged, OR is used with a 0.
So the mask for your case (leaving other bits unchanged) would be:
Binary: 10001000100010001000100010001000
Hex: 88888888

Resources